图片取模问题

也好嗯 2014-11-03 07:45:55
我在用Bmp2RGB.exe将240*320的bmp文件生成16bit的数组时,能显示出图片,但是显示出来的缺乏红色,也就是RGB三基色里面唯独红色没有显示,造成图片颜色失真

后来我又分别将全红,全绿,全蓝的图片分别显示,也唯独红色显示出来的是黑色,其他两种都正常显示

再接着我又准备生成18Bit的数组时,结果发现Bmp2RGB.exe不能生成18bit,生成的.h文件只有1KB

代码如下

u32 shift_picture(u32 color)
{
u32 r,g,b;
u32 out_color = 0;

r = (color & 0xFF0000) >> 16;//16位的数组文件在这里的结果只会是0,也就是丢掉红色的原因所在
g = (color & 0x00FF00) >> 8;
b = color & 0x0000FF;

switch(u8_LCDPixelFormat)//这里是图片显示格式,主函数里手动赋值为5或6都可以
{
case 3: // 12-bit
{
r = r >> 4;
g = g >> 4;
b = b >> 4;
out_color = (r << 8) | (g << 4) | b;
break;
}
case 5: // 16-bit
{
r = r >> 3;
g = g >> 2;
b = b >> 3;
out_color = (r << 11) | (g << 5) | b;
break;
}
case 6: // 18-bit
{
out_color = color & 0xFCFCFC;
break;
}
}
return out_color;
}

//
void printf_picture(dr35_LcdCoordinates_t coord,const u32* picture)//第一个参数是行地址和页地址的结构体,这里直接全屏显示,第二个参数就是图片的数组了
{
u16 x,y;
u8 odd_pixel = 0;
u32 prev_color = 0, current_color = 0;


p_dr35lcd_SetDisplayWindow(coord.x_ul, coord.x_lr, coord.y_ul, coord.y_lr);//全屏显示的意思
ILI9341WriteCmd(0x2c);//写显示内存的准备命令,无需理会

for(y = coord.y_ul; y <= coord.y_lr; y++)
{
for(x = coord.x_ul; x <= coord.x_lr; x++)
{
current_color = shift_picture(*picture);
picture++;


switch(u8_LCDPixelFormat)
{
case 3: // 12-bit
{
if (odd_pixel > 0)
{
ILI9341Write8bitData((prev_color >> 4) & 0xFF);
ILI9341Write8bitData((prev_color & 0xF) | ((current_color >> 8)) & 0xFF);
ILI9341Write8bitData(current_color & 0xFF);
}
break;
}
case 5: // 16-bit
{
ILI9341Write8bitData((current_color >> 8) & 0xFF);
ILI9341Write8bitData(current_color & 0xFF);
break;
}
case 6: // 18-bit
{
ILI9341Write8bitData((current_color >> 16) & 0xFF);
ILI9341Write8bitData((current_color >> 8) & 0xFF);
ILI9341Write8bitData(current_color & 0xFF);
break;
}
}
prev_color = current_color;
odd_pixel = (odd_pixel + 1) % 2;

}
}

}


(我在使用16bit的图片数组时,会把上面的u32改为u16)

想请教的问题有

1.有没有能生成18bit的图片取模软件?

2.rgb能用0x000000-0xFFFFFF表示这个我以前学过PS,懂!
但是用0x0000-0xffff表示是怎么个原理,请不吝赐我
...全文
629 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
也好嗯 2014-11-06
  • 打赏
  • 举报
回复
引用 18 楼 zhao4zhong1 的回复:
r = (color & 0xFF0000) >> 16; 和 r = (color & 0xFF0000u) >> 16; 不是一回事!参考:
#include <stdio.h>
unsigned char ui;
  signed char si;
char main() {
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=ui>>1;
    si=si>>1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("--------------\n");
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=((  signed char)ui)>>1;
    si=((unsigned char)si)>>1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("==============\n");

    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=ui<<1;
    si=si<<1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("--------------\n");
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=((  signed char)ui)<<1;
    si=((unsigned char)si)<<1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    return 0;
}
//ui=128
//si=-128
//ui=64
//si=-64
//--------------
//ui=128
//si=-128
//ui=192
//si=64
//==============
//ui=128
//si=-128
//ui=0
//si=0
//--------------
//ui=128
//si=-128
//ui=0
//si=0
C Integer Constants An “integer constant” is a decimal (base 10), octal (base 8), or hexadecimal (base 16) number that represents an integral value. Use integer constants to represent integer values that cannot be changed. Syntax integer-constant : decimal-constant integer-suffix opt octal-constant integer-suffix opt hexadecimal-constant integer-suffix opt decimal-constant : nonzero-digit decimal-constant digit octal-constant : 0 octal-constant octal-digit hexadecimal-constant : 0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit nonzero-digit : one of 1 2 3 4 5 6 7 8 9 octal-digit : one of 0 1 2 3 4 5 6 7 hexadecimal-digit : one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F integer-suffix : unsigned-suffix long-suffix opt long-suffix unsigned-suffix opt unsigned-suffix : one of u U long-suffix : one of l L 64-bit integer-suffix : i64 Integer constants are positive unless they are preceded by a minus sign (–). The minus sign is interpreted as the unary arithmetic negation operator. (See Unary Arithmetic Operators in Chapter 4 for information about this operator.) If an integer constant begins with the letters 0x or 0X, it is hexadecimal. If it begins with the digit 0, it is octal. Otherwise, it is assumed to be decimal. The following lines are equivalent: 0x1C /* = Hexadecimal representation for decimal 28 */ 034 /* = Octal representation for decimal 28 */ No white-space characters can separate the digits of an integer constant. These examples show valid decimal, octal, and hexadecimal constants. /* Decimal Constants */ 10 132 32179 /* Octal Constants */ 012 0204 076663 /* Hexadecimal Constants */ 0xa or 0xA 0x84 0x7dB3 or 0X7DB3
多谢赵老师解疑答惑,我已经解决了,祝你每天生活愉快(这大段代码和颜色有关系么?)
赵4老师 2014-11-05
  • 打赏
  • 举报
回复
r = (color & 0xFF0000) >> 16; 和 r = (color & 0xFF0000u) >> 16; 不是一回事!参考:
#include <stdio.h>
unsigned char ui;
  signed char si;
char main() {
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=ui>>1;
    si=si>>1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("--------------\n");
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=((  signed char)ui)>>1;
    si=((unsigned char)si)>>1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("==============\n");

    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=ui<<1;
    si=si<<1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    printf("--------------\n");
    ui=(unsigned char)0x80u;
    si=(  signed char)0x80;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);
    ui=((  signed char)ui)<<1;
    si=((unsigned char)si)<<1;
    printf("ui=%u\n",ui);
    printf("si=%d\n",si);

    return 0;
}
//ui=128
//si=-128
//ui=64
//si=-64
//--------------
//ui=128
//si=-128
//ui=192
//si=64
//==============
//ui=128
//si=-128
//ui=0
//si=0
//--------------
//ui=128
//si=-128
//ui=0
//si=0
C Integer Constants An “integer constant” is a decimal (base 10), octal (base 8), or hexadecimal (base 16) number that represents an integral value. Use integer constants to represent integer values that cannot be changed. Syntax integer-constant : decimal-constant integer-suffix opt octal-constant integer-suffix opt hexadecimal-constant integer-suffix opt decimal-constant : nonzero-digit decimal-constant digit octal-constant : 0 octal-constant octal-digit hexadecimal-constant : 0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit nonzero-digit : one of 1 2 3 4 5 6 7 8 9 octal-digit : one of 0 1 2 3 4 5 6 7 hexadecimal-digit : one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F integer-suffix : unsigned-suffix long-suffix opt long-suffix unsigned-suffix opt unsigned-suffix : one of u U long-suffix : one of l L 64-bit integer-suffix : i64 Integer constants are positive unless they are preceded by a minus sign (–). The minus sign is interpreted as the unary arithmetic negation operator. (See Unary Arithmetic Operators in Chapter 4 for information about this operator.) If an integer constant begins with the letters 0x or 0X, it is hexadecimal. If it begins with the digit 0, it is octal. Otherwise, it is assumed to be decimal. The following lines are equivalent: 0x1C /* = Hexadecimal representation for decimal 28 */ 034 /* = Octal representation for decimal 28 */ No white-space characters can separate the digits of an integer constant. These examples show valid decimal, octal, and hexadecimal constants. /* Decimal Constants */ 10 132 32179 /* Octal Constants */ 012 0204 076663 /* Hexadecimal Constants */ 0xa or 0xA 0x84 0x7dB3 or 0X7DB3
也好嗯 2014-11-05
  • 打赏
  • 举报
回复
引用 15 楼 gqjjqg 的回复:
我不太理解你哪里不明白。 我没有取模软件,搜了一下,取模是指取字模吗? 字模之类的,freeType 可以满足你的各种需求。 看你提供的代码,仅仅是颜色格式上的转换而已,完全可以自己按需求写。
刚刚我已经搞定了,就你最有耐心,分全都给你了
也好嗯 2014-11-05
  • 打赏
  • 举报
回复
引用 15 楼 gqjjqg 的回复:
我不太理解你哪里不明白。 我没有取模软件,搜了一下,取模是指取字模吗? 字模之类的,freeType 可以满足你的各种需求。 看你提供的代码,仅仅是颜色格式上的转换而已,完全可以自己按需求写。
取模还指图片取模,freeType也不错
gqjjqg 2014-11-05
  • 打赏
  • 举报
回复
引用 14 楼 liaocao2010 的回复:
话说,@gqjjqg,您有好的取模软件么
我不太理解你哪里不明白。 我没有取模软件,搜了一下,取模是指取字模吗? 字模之类的,freeType 可以满足你的各种需求。 看你提供的代码,仅仅是颜色格式上的转换而已,完全可以自己按需求写。
也好嗯 2014-11-05
  • 打赏
  • 举报
回复
话说,@gqjjqg,您有好的取模软件么
也好嗯 2014-11-05
  • 打赏
  • 举报
回复
引用 12 楼 gqjjqg 的回复:
分析红色不显示的问题,先要知道输入的color 是RGB888?还是RGBA8888,亦或者是其他各种格式。 目测代码要求输入的是RGB888或者BGR888。你输入16bit的数值,果断就出问题。 修复的办法很简单,输入值改成RGB888的格式就行了。
不是很明白RGB888是什么意思,我现在能确定的是0xf800是红色,0x07e0是绿色,0x001f是蓝色,也就是565 也不知道是不是我的取模软件有问题,直接显示颜色就行,用图片取模生成的数组颜色就是不正,现在也不是缺少红色了,我修改后,发现图片中的颜色能把蓝色显示成绿色,单独显示蓝色又没问题
gqjjqg 2014-11-05
  • 打赏
  • 举报
回复
引用 10 楼 liaocao2010 的回复:
[quote=引用 9 楼 gqjjqg 的回复:] 1.有没有能生成18bit的图片取模软件? 我没发现有这样的软件,RGB 666 每个通道 6bit,目测要自己写,代码不算复杂。 2.rgb能用0x000000-0xFFFFFF表示这个我以前学过PS,懂! 但是用0x0000-0xffff表示是怎么个原理,请不吝赐我 0x000-0xffff 只是存储的范围,5 6 5也仅仅表示存储时 R 5bit G6bit B5bit。显示时还是按各个通道 把这些扩展回去。当然这个和硬件设备有关系。
我很喜欢你解答的风格,我忘记了问一个关键的问题,“显示不了红色是为什么?” 这段代码要咋改 r = r >> 3; g = g >> 2; b = b >> 3; out_color = (r << 11) | (g << 5) | b;[/quote]
引用 10 楼 liaocao2010 的回复:
[quote=引用 9 楼 gqjjqg 的回复:] 1.有没有能生成18bit的图片取模软件? 我没发现有这样的软件,RGB 666 每个通道 6bit,目测要自己写,代码不算复杂。 2.rgb能用0x000000-0xFFFFFF表示这个我以前学过PS,懂! 但是用0x0000-0xffff表示是怎么个原理,请不吝赐我 0x000-0xffff 只是存储的范围,5 6 5也仅仅表示存储时 R 5bit G6bit B5bit。显示时还是按各个通道 把这些扩展回去。当然这个和硬件设备有关系。
我很喜欢你解答的风格,我忘记了问一个关键的问题,“显示不了红色是为什么?” 这段代码要咋改 r = r >> 3; g = g >> 2; b = b >> 3; out_color = (r << 11) | (g << 5) | b;[/quote] 分析红色不显示的问题,先要知道输入的color 是RGB888?还是RGBA8888,亦或者是其他各种格式。 目测代码要求输入的是RGB888或者BGR888。你输入16bit的数值,果断就出问题。 修复的办法很简单,输入值改成RGB888的格式就行了。
赵4老师 2014-11-04
  • 打赏
  • 举报
回复
参考 Image Magick CXImage
也好嗯 2014-11-04
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
仅供参考
#include <stdio.h>
#include <string.h>
#include <conio.h>
FILE *fi,*fo;
unsigned int n;
int c;
//-------------------------------------------------------
void main(int argc,char *argv[])
{
    if (argc<3) {
        cprintf("Bin2Hex srcfile desfile");
        return;
    }
    if ((fi=fopen(argv[1],"rb"))==NULL) {
        cprintf("Can not find file %s",argv[1]);
        return;
    }
    if ((fo=fopen(argv[2],"w"))==NULL) {
        fclose(fi);
        cprintf("Can not create file %s",argv[2]);
        return;
    }
    n=0;
    while (1) {
        c=fgetc(fi);
        if (EOF==c) break;
        n++;
        if (1==n)        fprintf(fo,  "0x%02X",c);
        else {
            if (1==n%16) fprintf(fo,"\n0x%02X",c);
            else         fprintf(fo, ",0x%02X",c);
        }
    }
    fcloseall();
    cprintf("OK to Bin2Hex %u bytes.",n);
}
赵老师,您能详细说说图片取模生成16bit的c数组应该怎么写RBG的函数才能不失真么,万分感谢了
赵4老师 2014-11-04
  • 打赏
  • 举报
回复
仅供参考
#include <stdio.h>
#include <string.h>
#include <conio.h>
FILE *fi,*fo;
unsigned int n;
int c;
//-------------------------------------------------------
void main(int argc,char *argv[])
{
    if (argc<3) {
        cprintf("Bin2Hex srcfile desfile");
        return;
    }
    if ((fi=fopen(argv[1],"rb"))==NULL) {
        cprintf("Can not find file %s",argv[1]);
        return;
    }
    if ((fo=fopen(argv[2],"w"))==NULL) {
        fclose(fi);
        cprintf("Can not create file %s",argv[2]);
        return;
    }
    n=0;
    while (1) {
        c=fgetc(fi);
        if (EOF==c) break;
        n++;
        if (1==n)        fprintf(fo,  "0x%02X",c);
        else {
            if (1==n%16) fprintf(fo,"\n0x%02X",c);
            else         fprintf(fo, ",0x%02X",c);
        }
    }
    fcloseall();
    cprintf("OK to Bin2Hex %u bytes.",n);
}
也好嗯 2014-11-04
  • 打赏
  • 举报
回复
引用 2 楼 lovesmiles 的回复:
那里有18bit的东西?只有2的n次方的bit。18bit不轮不类,你一般的软件生成不了这样的bmp。

0x000000-0xFFFFFF是三字节,一个颜色通道点一字节。
0x0000-0xffff是二字节,二个颜色通道占10bit,一个颜色通道点6bit。

你的程序输入是32位的数据,你就要用32位的图片,用其它图片格式没有用的




我也觉得18bit的好奇怪,偏偏代码以前的记录里有,这个软件里也有选项,就是生成不了

那0x000000-0xFFFFFF是不是要生成24bit的c数组啊,貌似我的datasheet里面是说18bit是mcu的一种接口模式

32位的图片能通过ps生成,那么用什么软件能取模生成相应的c数组文件呢
也好嗯 2014-11-04
  • 打赏
  • 举报
回复
引用 1 楼 relaxisland 的回复:
ILI9341Write8bitData((current_color >> 16) & 0xFF); ILI9341Write8bitData((current_color >> 8) & 0xFF); ILI9341Write8bitData(current_color & 0xFF); 这个有问题啊, 按你前面的那个函数来说, rgb应该是分别5bit,6bit,5bit 所以应该是 ILI9341Write8bitData((current_color >> 11) & 0xFF); ILI9341Write8bitData((current_color <<5>>11) & 0xFF); ILI9341Write8bitData(current_color <<11>>11& 0xFF);
5、6、5不就是16bit么,这个不就是直接使用 ILI9341Write8bitData((current_color >> 8) & 0xFF); ILI9341Write8bitData(current_color & 0xFF); 这两条代码就好了么,write8bitdata一次就是写8位数据啊,我把这代码拷贝到工程里去运行,显示不了哦 感谢您的回复,祝你每天生活愉快!^_^
也好嗯 2014-11-04
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
http://www.baidu.com/s?wd=18%E4%BD%8DRGB&rsv_spt=1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_sug3=4&rsv_sug=0&rsv_sug1=4&rsv_sug4=110&inputT=7828
赵老师,能否稍微爆发一下您的小宇宙, 这段代码到底要咋改
u32 shift_picture(u32 color)
{
    u32 r,g,b;
    u32 out_color = 0;
 
    r = (color & 0xFF0000) >> 16;//16位的数组文件在这里的结果只会是0,也就是丢掉红色的原因所在
    g = (color & 0x00FF00) >> 8;
    b = color & 0x0000FF;
 
    switch(u8_LCDPixelFormat)//这里是图片显示格式,主函数里手动赋值为5或6都可以
    {
        case 3: // 12-bit
        {
            r = r >> 4;
            g = g >> 4;
            b = b >> 4;
            out_color = (r << 8) | (g << 4) | b;
            break;
        }
        case 5: // 16-bit
        {
            r = r >> 3;
            g = g >> 2;
            b = b >> 3;
            out_color = (r << 11) | (g << 5) | b;
            break;
        }
        case 6: // 18-bit
        {
            out_color = color & 0xFCFCFC;
            break;
        }
    }
    return out_color;
}
也好嗯 2014-11-04
  • 打赏
  • 举报
回复
引用 9 楼 gqjjqg 的回复:
1.有没有能生成18bit的图片取模软件? 我没发现有这样的软件,RGB 666 每个通道 6bit,目测要自己写,代码不算复杂。 2.rgb能用0x000000-0xFFFFFF表示这个我以前学过PS,懂! 但是用0x0000-0xffff表示是怎么个原理,请不吝赐我 0x000-0xffff 只是存储的范围,5 6 5也仅仅表示存储时 R 5bit G6bit B5bit。显示时还是按各个通道 把这些扩展回去。当然这个和硬件设备有关系。
我很喜欢你解答的风格,我忘记了问一个关键的问题,“显示不了红色是为什么?” 这段代码要咋改 r = r >> 3; g = g >> 2; b = b >> 3; out_color = (r << 11) | (g << 5) | b;
gqjjqg 2014-11-04
  • 打赏
  • 举报
回复
1.有没有能生成18bit的图片取模软件? 我没发现有这样的软件,RGB 666 每个通道 6bit,目测要自己写,代码不算复杂。 2.rgb能用0x000000-0xFFFFFF表示这个我以前学过PS,懂! 但是用0x0000-0xffff表示是怎么个原理,请不吝赐我 0x000-0xffff 只是存储的范围,5 6 5也仅仅表示存储时 R 5bit G6bit B5bit。显示时还是按各个通道 把这些扩展回去。当然这个和硬件设备有关系。
勤奋的小游侠 2014-11-03
  • 打赏
  • 举报
回复
那里有18bit的东西?只有2的n次方的bit。18bit不轮不类,你一般的软件生成不了这样的bmp。 0x000000-0xFFFFFF是三字节,一个颜色通道点一字节。 0x0000-0xffff是二字节,二个颜色通道占10bit,一个颜色通道点6bit。 你的程序输入是32位的数据,你就要用32位的图片,用其它图片格式没有用的
relaxisland 2014-11-03
  • 打赏
  • 举报
回复
ILI9341Write8bitData((current_color >> 16) & 0xFF); ILI9341Write8bitData((current_color >> 8) & 0xFF); ILI9341Write8bitData(current_color & 0xFF); 这个有问题啊, 按你前面的那个函数来说, rgb应该是分别5bit,6bit,5bit 所以应该是 ILI9341Write8bitData((current_color >> 11) & 0xFF); ILI9341Write8bitData((current_color <<5>>11) & 0xFF); ILI9341Write8bitData(current_color <<11>>11& 0xFF);

69,374

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧