zoukankan      html  css  js  c++  java
  • FreeImage中 FIBITMAP与HBITMAP互相转化

    文件位置"FreeImage/TestAPI/testMemIO.cpp"

    // ==========================================================
    // FreeImage 3 Test Script
    //
    // Design and implementation by
    // - Herv?Drolon (drolon@infonie.fr)
    //
    // This file is part of FreeImage 3
    //
    // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
    // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
    // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
    // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
    // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
    // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
    // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
    // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
    // THIS DISCLAIMER.
    //
    // Use at your own risk!
    // ==========================================================
    
    #include <windows.h>
    #include "TestSuite.h"
    
    
    // 保存HBITMAP对应的文件
    int save_bitmap_to_file(HBITMAP hBitmap, char *bitmap_filename);
    
    void testHBitmapMemIO(const char* qlpszPathName)
    {
        char* lpszPathName = "a.mgm";
        struct stat buf;
        int result;
    
        // get data associated with lpszPathName
        result = stat(lpszPathName, &buf);
        if(result == 0) {
            // allocate a memory buffer and load temporary data
            BYTE *mem_buffer = (BYTE*)malloc(buf.st_size * sizeof(BYTE));
            if(mem_buffer) {
                FILE *stream = fopen(lpszPathName, "rb");
                if(stream) {
                    fread(mem_buffer, sizeof(BYTE), buf.st_size, stream);
                    fclose(stream);
    
                    // attach the binary data to a memory stream
                    FIMEMORY *hmem = FreeImage_OpenMemory(mem_buffer, buf.st_size);
    
                    // get the file type
                    FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem, 0);
    
                    // load an image from the memory stream
                    FIBITMAP *dib = FreeImage_LoadFromMemory(fif, hmem, PNG_DEFAULT);
    
                    {
                        HBITMAP hBitmap;
                        HDC hdc;
                        // FIBITMAP转换HBITMAP
                        {
                            hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);//为屏幕创建设备描述表
                            hBitmap = CreateDIBitmap(hdc, FreeImage_GetInfoHeader(dib),
                                                     CBM_INIT,
                                                     FreeImage_GetBits(dib),
                                                     FreeImage_GetInfo(dib),
                                                     DIB_RGB_COLORS);
                            //DeleteDC(hdc);
                            save_bitmap_to_file(hBitmap, "aFIBITMAP2HBITMAP.bmp");
                        }
    
                        // HBITMAP转换FIBITMAP
                        // the following code assumes that you have a valid HBITMAP loaded into the memory
                        {
                            HBITMAP hBitmap_2 = (HBITMAP)LoadImageA(NULL, "aFIBITMAP2HBITMAP.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
                            BITMAP bm_info;
                            GetObject(hBitmap_2, sizeof(BITMAP), (LPSTR)&bm_info);
                            FIBITMAP* dib_new = FreeImage_Allocate(bm_info.bmWidth, bm_info.bmHeight, bm_info.bmBitsPixel);
                            // The GetDIBits function clears the biClrUsed and biClrImportant BITMAPINFO members (dont't know why) 
                            // So we save these infos below. This is needed for palettized images only. 
                            int Success = GetDIBits(hdc, hBitmap_2, 0, FreeImage_GetHeight(dib_new),
                                                    FreeImage_GetBits(dib_new), FreeImage_GetInfo(dib_new), DIB_RGB_COLORS);
                            // restore BITMAPINFO members
                            int nColors = FreeImage_GetColorsUsed(dib_new);
                            FreeImage_GetInfoHeader(dib_new)->biClrUsed = nColors;
                            FreeImage_GetInfoHeader(dib_new)->biClrImportant = nColors;
    
                            FreeImage_Save(FIF_BMP, dib_new, "aHBITMAP2FIBITMAP.bmp", BMP_DEFAULT);
                        }
    
                        DeleteDC(hdc);
                    }
    
                    // save as a regular file
                    //FreeImage_Save(FIF_PNG, dib, "blob.png", PNG_DEFAULT);
                    FreeImage_Unload(dib);
    
                    // close the stream
                    FreeImage_CloseMemory(hmem);
    
                }
            }
            // user is responsible for freeing the data
            free(mem_buffer);
        }
    }
    
    void testSaveMemIO(const char *lpszPathName) {
    	FIMEMORY *hmem = NULL; 
    
    	// load a regular file
    	FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(lpszPathName);
    	FIBITMAP *dib = FreeImage_Load(fif, lpszPathName, 0);
    	
    	// open a memory handle
    	hmem = FreeImage_OpenMemory();
    
    	// save the file to memory
    	FreeImage_SaveToMemory(fif, dib, hmem, 0);
    
    	// at this point, hmem contains the entire FREE_IMAGE_FORMAT data in memory. 
    	// the amount of space used by the memory is equal to file_size
    	FreeImage_SeekMemory(hmem, 0, SEEK_END);
    	long file_size = FreeImage_TellMemory(hmem);
    	printf("File size : %ld
    ", file_size);
    
    
    	// its easy load an image from memory as well
    
    	// seek to the start of the memory stream
    	FreeImage_SeekMemory(hmem, 0L, SEEK_SET);
    	
    	// get the file type
    	FREE_IMAGE_FORMAT mem_fif = FreeImage_GetFileTypeFromMemory(hmem, 0);
    	
    	// load an image from the memory handle 
    	FIBITMAP *check = FreeImage_LoadFromMemory(mem_fif, hmem, 0);
    
    	// save as a regular file
    	FreeImage_Save(FIF_PNG, check, "dump.png", PNG_DEFAULT);
    
    	// make sure to free the data since FreeImage_SaveToMemory 
    	// will cause it to be malloc'd
    	FreeImage_CloseMemory(hmem);
    
    	FreeImage_Unload(check);
    	FreeImage_Unload(dib);
    }
    
    	//you could also have image data in memory via some other method, and just set
    	//fmh.data to point to it, and set both fmh.datalen and fmh.filelen to the
    	//size of that data, then FreeImage_LoadFromMemory could load the image from that memory
    
    void testLoadMemIO(const char *lpszPathName) {
    	struct stat buf;
    	int result;
    
    	// get data associated with lpszPathName
    	result = stat(lpszPathName, &buf);
    	if(result == 0) {
    		// allocate a memory buffer and load temporary data
    		BYTE *mem_buffer = (BYTE*)malloc(buf.st_size * sizeof(BYTE));
    		if(mem_buffer) {
    			FILE *stream = fopen(lpszPathName, "rb");
    			if(stream) {
    				fread(mem_buffer, sizeof(BYTE), buf.st_size, stream);
    				fclose(stream);
    
    				// attach the binary data to a memory stream
    				FIMEMORY *hmem = FreeImage_OpenMemory(mem_buffer, buf.st_size);
    
    				// get the file type
    				FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(hmem, 0);
    
    				// load an image from the memory stream
    				FIBITMAP *check = FreeImage_LoadFromMemory(fif, hmem, PNG_DEFAULT);
    
    				// save as a regular file
    				FreeImage_Save(FIF_PNG, check, "blob.png", PNG_DEFAULT);
    				FreeImage_Unload(check);
    				
    				// close the stream
    				FreeImage_CloseMemory(hmem);
    
    			}
    		}
    		// user is responsible for freeing the data
    		free(mem_buffer);
    	}
    }
    
    void testAcquireMemIO(const char *lpszPathName) {
    	FIMEMORY *hmem = NULL; 
    
    	// load a regular file
    	FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(lpszPathName);
    	FIBITMAP *dib = FreeImage_Load(fif, lpszPathName, 0);
    
    	// open and allocate a memory stream
    	hmem = FreeImage_OpenMemory();
    
    	// save the file to memory
    	FreeImage_SaveToMemory(FIF_PNG, dib, hmem, PNG_DEFAULT);
    
    	FreeImage_Unload(dib);
    
    	// get the buffer from the memory stream
    	BYTE *mem_buffer = NULL;
    	DWORD size_in_bytes = 0;
    
    	FreeImage_AcquireMemory(hmem, &mem_buffer, &size_in_bytes);
    
    	// save the buffer in a file stream
    	FILE *stream = fopen("buffer.png", "wb");
    	if(stream) {
    		fwrite(mem_buffer, sizeof(BYTE), size_in_bytes, stream);
    		fclose(stream);
    	}
    
    	// close and free the memory stream
    	FreeImage_CloseMemory(hmem);
    
    }
    
    void testMemIO(const char *lpszPathName) {
    	printf("testMemIO ...
    ");
        testHBitmapMemIO(lpszPathName);
    	testSaveMemIO(lpszPathName);
    	testLoadMemIO(lpszPathName);
    	testAcquireMemIO(lpszPathName);
    }
    
    
    
    
    
    
    
    
    
    // 保存HBITMAP对应的文件
    int save_bitmap_to_file(HBITMAP hBitmap, char *bitmap_filename)
    {
        if(NULL == hBitmap) {
            return -1;
        }
    
        HDC   hDC;
        int   bits_len;//当前分辨率下每象素所占字节数
        WORD  bit_count;//位图中每象素所占字节数
        DWORD palette_size = 0;//定义调色板大小
        DWORD bitmap_bits_size = 0;//位图中像素字节大小
        DWORD bitmap_file_size = 0;//位图文件大小
        DWORD dwWritten = 0;//写入文件字节数
    
        BITMAP bitmap;//位图属性结构
    
        BITMAPFILEHEADER     file_head;//位图文件头结构
        BITMAPINFOHEADER     file_head_info;//位图信息头结构
        LPBITMAPINFOHEADER   p_file_head_info;//指向位图信息头结构
    
        HANDLE hFile, hMem, hPalette, hPaletteOld = NULL;//定义文件,分配内存句柄,调色板句柄
    
        //计算位图文件每个像素所占字节数
        hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
        bits_len = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
        DeleteDC(hDC);
    
        if(bits_len <= 1) {
            bit_count = 1;
        } else  if(bits_len <= 4) {
            bit_count = 4;
        } else if(bits_len <= 8) {
            bit_count = 8;
        } else {
            bit_count = 24;
        }
    
        GetObject(hBitmap, sizeof(bitmap), (LPSTR)&bitmap);
        file_head_info.biSize = sizeof(BITMAPINFOHEADER);
        file_head_info.biWidth = bitmap.bmWidth;
        file_head_info.biHeight = bitmap.bmHeight;
        file_head_info.biPlanes = 1;
        file_head_info.biBitCount = bit_count;
        file_head_info.biCompression = BI_RGB;
        file_head_info.biSizeImage = 0;
        file_head_info.biXPelsPerMeter = 0;
        file_head_info.biYPelsPerMeter = 0;
        file_head_info.biClrImportant = 0;
        file_head_info.biClrUsed = 0;
    
        bitmap_bits_size = ((bitmap.bmWidth * bit_count + 31) / 32) * 4 * bitmap.bmHeight;
    
        //为位图内容分配内存
        hMem = GlobalAlloc(GHND, bitmap_bits_size + palette_size + sizeof(BITMAPINFOHEADER));
        p_file_head_info = (LPBITMAPINFOHEADER)GlobalLock(hMem);
        *p_file_head_info = file_head_info;
    
        // 处理调色板
        hPalette = GetStockObject(DEFAULT_PALETTE);
        if(hPalette) {
            hDC = ::GetDC(NULL);
            hPaletteOld = ::SelectPalette(hDC, (HPALETTE)hPalette, FALSE);
            RealizePalette(hDC);
        }
    
        // 获取该调色板下新的像素值
        GetDIBits(hDC, hBitmap, 0, (UINT)bitmap.bmHeight,
                  (LPSTR)p_file_head_info + sizeof(BITMAPINFOHEADER)+palette_size,
                  (BITMAPINFO *)p_file_head_info, DIB_RGB_COLORS);
    
        // 恢复调色板
        if(hPaletteOld) {
            ::SelectPalette(hDC, (HPALETTE)hPaletteOld, TRUE);
            RealizePalette(hDC);
            ::ReleaseDC(NULL, hDC);
        }
    
        // 创建位图文件
        hFile = CreateFileA(bitmap_filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    
        if(hFile == INVALID_HANDLE_VALUE) {
            return S_FALSE;
        }
    
        // 设置位图文件头
        file_head.bfType = 0x4D42;     //     "BM"
        bitmap_file_size = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+palette_size + bitmap_bits_size;
        file_head.bfSize = bitmap_file_size;
        file_head.bfReserved1 = 0;
        file_head.bfReserved2 = 0;
        file_head.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+palette_size;
        // 写入位图文件头
        WriteFile(hFile, (LPSTR)&file_head, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
        // 写入位图文件其余内容
        WriteFile(hFile, (LPSTR)p_file_head_info, bitmap_file_size, &dwWritten, NULL);
    
        // 清除
        GlobalUnlock(hMem);
        GlobalFree(hMem);
        CloseHandle(hFile);
    
        return S_OK;
    }
    

      

  • 相关阅读:
    音视频入门-06-代码画图时间
    音视频入门-05-RGB-TO-BMP使用开源库
    音视频入门-04-BMP图像四字节对齐的问题
    音视频入门-03-RGB转成BMP图片
    控制input文本框只能输入正整数(H5)
    微信小程序自定义导航栏配置(顶部栏搜索框)
    React-日历组件(原生JS代码)
    package.json文件详解
    解决HTML5IOS拍照上传图片逆时针旋转90度问题(React)
    项目细节
  • 原文地址:https://www.cnblogs.com/baigoogledu/p/5276142.html
Copyright © 2011-2022 走看看