清风

导航

用libjpeg把jpg转换成winapi的bmp(BITMAP)

  1 #include <stdio.h> // jpeglib需要FILE和size_t的定义
  2 #include <windows.h>
  3 #include "debug.h"
  4 #include "jpeglib.h"
  5 #pragma comment(lib, "libjpeg.lib")
  6 
  7 extern HBITMAP jpg2bmp(unsigned char *jpg_buffer, unsigned jpg_size)
  8 {
  9     int rc;
 10     struct jpeg_decompress_struct cinfo;
 11     struct jpeg_error_mgr jerr;
 12     BITMAPINFO bi; // = {};
 13     LPBYTE lpBuf, pb = NULL;
 14     HBITMAP hbm;    
 15     JSAMPARRAY buffer; // {};
 16     INT row = 0;
 17     
 18     DEBUG_PUTS("读取jpg");
 19 
 20     cinfo.err = jpeg_std_error(&jerr);
 21     jpeg_create_decompress(&cinfo);
 22 
 23     jpeg_mem_src(&cinfo, jpg_buffer, jpg_size);
 24 
 25     rc = jpeg_read_header(&cinfo, TRUE); // read jpeg file header
 26 
 27     if (rc != 1) {
 28         // File does not seem to be a normal JPEG
 29         return NULL;
 30     }
 31     
 32     jpeg_start_decompress(&cinfo);  // decompress the file
 33 
 34     row = ((cinfo.output_width * 3 + 3) & ~3);
 35     buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE,
 36         row, 1);
 37 
 38     ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER));
 39     bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 40     bi.bmiHeader.biWidth = cinfo.output_width;
 41     bi.bmiHeader.biHeight = cinfo.output_height;
 42     bi.bmiHeader.biPlanes = 1;
 43     bi.bmiHeader.biBitCount = 24;
 44     bi.bmiHeader.biCompression = BI_RGB;
 45     bi.bmiHeader.biSizeImage = row * cinfo.output_height;
 46 
 47     hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&lpBuf, NULL, 0);
 48     
 49     if (hbm == NULL)
 50     {
 51         DEBUG_PUTS("hbm NULL");
 52         jpeg_destroy_decompress(&cinfo);
 53         return NULL;
 54     }
 55     
 56     DEBUG_PUTS("hbm正常");
 57 
 58     pb = lpBuf + row * cinfo.output_height;
 59     DEBUG_PRINTF("行 %d 输出高度 %d\n", row, cinfo.output_height);
 60     while (cinfo.output_scanline < cinfo.output_height)
 61     {
 62         pb -= row;
 63         jpeg_read_scanlines(&cinfo, buffer, 1);
 64 
 65         if (cinfo.out_color_components == 1)
 66         {
 67             UINT i;
 68             LPBYTE p = (LPBYTE)buffer[0];
 69             
 70             for (i = 0; i < cinfo.output_width; i++)
 71                 pb[3 * i + 0] = pb[3 * i + 1] = pb[3 * i + 2] = p[i];
 72         }
 73         else if (cinfo.out_color_components == 3)
 74         {
 75             // There was talk on Internet about one being RGB and another BGR. 
 76             // If colors appear swapped, then swap the bytes, and update this comment.
 77             // CopyMemory(pb, buffer[0], row);
 78 
 79             // Updated color correction
 80             UINT i;
 81             LPBYTE p = (LPBYTE)buffer[0];
 82             
 83             for (i = 0; i < row; i += 3)
 84             {
 85                 pb[i + 0] = p[i + 2]; // Blue
 86                 pb[i + 1] = p[i + 1]; // Green  
 87                 pb[i + 2] = p[i + 0]; // Red
 88             }
 89         }
 90         else
 91         {
 92             DEBUG_PUTS("【异常】cinfo.out_color_components无效");
 93             jpeg_destroy_decompress(&cinfo);
 94             DeleteObject(hbm);
 95             return NULL;
 96         }
 97     }
 98 
 99     DEBUG_PUTS("即将调用SetDIBits");
100 
101     SetDIBits(NULL, hbm, 0, cinfo.output_height, lpBuf, &bi, DIB_RGB_COLORS);
102 
103     jpeg_finish_decompress(&cinfo);
104     jpeg_destroy_decompress(&cinfo);
105 
106     return hbm;
107 }

 

posted on 2020-11-22 15:23  清风2009  阅读(334)  评论(0编辑  收藏  举报