linux 在LCD(ARGB)显示器上显示裁剪的JPEG时出错

omhiaaxx  于 2023-06-29  发布在  Linux
关注(0)|答案(2)|浏览(142)

我正试图裁剪一张大的JPEG照片,并将其显示到我的Linux中的LCD显示器上。
我使用libjpeg来解码照片,并将RGB转换为ARGB以在LCD上显示裁剪部分。
但是裁剪后的部分在LCD上显示时颜色不正确,使用以下代码进行解码,裁剪,ARGB转换并在帧缓冲区中显示。

unsigned char* output_buffer = (unsigned char*)malloc(sizeof(unsigned char) * varinfo.xres * varinfo.yres * 4);

    int row_stride = cinfo.output_width * cinfo.output_components;

    unsigned long rgb_size;
    unsigned char *rgb_data;
    rgb_size = row_stride * cinfo.output_height;
    rgb_data = (unsigned char *)calloc(1, rgb_size);

    jpeg_skip_scanlines(&cinfo, y_offset);

    int last_line = cinfo.output_scanline + varinfo.yres;
    last_line = (last_line > cinfo.output_height) ? cinfo.output_height : last_line;

    unsigned char* output_ptr = output_buffer;
    int count = 0;
    while (cinfo.output_scanline < last_line) {
        unsigned char *buffer_array[1];
        buffer_array[0] = rgb_data + (count++) * row_stride;
        jpeg_read_scanlines(&cinfo, buffer_array, 1);
    }

    for (int y = 0; y < varinfo.yres; y++) {
        unsigned char* row_ptr = rgb_data + y * row_stride + (3 * x_offset);
        for (int x = 0; x < varinfo.xres; x++) {
            *output_ptr++ = *row_ptr++;  // Red
            *output_ptr++ = *row_ptr++;  // Green
            *output_ptr++ = *row_ptr++;  // Blue
            *output_ptr++ = 0xFF;  // Alpha
        }
    }

    memcpy(fb_mem, output_buffer, (sizeof(uint32_t) * varinfo.xres * varinfo.yres));

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    free(output_buffer);
    free(rgb_data);

代码可以裁剪照片,但当裁剪的部分显示在LCD(帧缓冲区)中时,颜色不正确。
执行程序在调用jpeg_finish_decompress(&cinfo);时还报告以下错误

Application transferred too few scanlines

我不知道上面的代码有什么问题。

vcudknz3

vcudknz31#

我有一个类似的问题,它被称为当我没有阅读整个转移的图像,但只有一部分。因此,output_scanline字段没有获取图像的高度,而jpeg_finish_decompress函数导致了此错误。要决定,最好是阅读整个图像,只有这样,在某个地方的一面,裁剪到所需的大小。如果此选项不适合您,则可以将图像height的值分配给output_scanline字段,但这是一个不好的选项。

r7knjye2

r7knjye22#

颜色的问题来自代码。

for (int y = 0; y < varinfo.yres; y++) {
        unsigned char* row_ptr = rgb_data + y * row_stride + (3 * x_offset);
        for (int x = 0; x < varinfo.xres; x++) {
            *output_ptr++ = *row_ptr++;  // Red
            *output_ptr++ = *row_ptr++;  // Green
            *output_ptr++ = *row_ptr++;  // Blue
            *output_ptr++ = 0xFF;  // Alpha
        }
    }

要以ARGB显示图片,32位ARGB数据应该是0xAARRGGBB,但上述代码生成的像素为0xAABBGGRR。所以正确的应该是如下,

for (int y = 0; y < varinfo.yres; y++) {
        unsigned char* row_ptr = rgb_data + y * row_stride + (cinfo.output_components * x_offset);
        for (int x = 0; x < varinfo.xres; x++) {
            int r = *row_ptr++;
            int g = *row_ptr++;
            int b = *row_ptr++;
            *output_ptr++ = b;
            *output_ptr++ = g;
            *output_ptr++ = r;
            *output_ptr++ = 0xFF;  // Alpha
        }
    }

相关问题