用libjpeg把jpg轉換成winapi的bmp(BITMAP)
阿新 • • 發佈:2020-11-22
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 }