bmp格式转换PNG格式 c语言或c++编程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bmp格式转换PNG格式 c语言或c++编程相关的知识,希望对你有一定的参考价值。

求程序,需要将BMP格式图片转换为PNG图片格式,需要c语言或c++编程程序,高手请赐教。

BMP是最简单的图形存储格式,在c++里有朋友封装了一个类CDib.
只要把图片使用附件中编辑--粘贴来源找到图画打开另存为选择你想要的格式保存就可以了。也可以右键点击选择打开方式使用图画打开相同的方法。另外photoshop 和office2003的picture manage也有这个功能。

Private Sub mnuconvertBMPtoJPG_Click()
Dim tmpimage As imgdes ' Image descriptors
Dim tmp2image As imgdes
Dim rcode As Long
Dim quality As Long
Dim vbitcount As Long
Dim bdat As BITMAPINFOHEADER ' Reserve space for BMP struct
Dim bmp_fname As String
Dim jpg_fname As String

bmp_fname = "test.bmp"
jpg_fname = "test.jpg"

quality = 75
' Get info on the file we're to load
rcode = bmpinfo(bmp_fname, bdat)
If (rcode <> NO_ERROR) Then
MsgBox "Cannot find file", 0, "Error encountered!"
Exit Sub
End If

vbitcount = bdat.biBitCount
If (vbitcount >= 16) Then ' 16-, 24-, or 32-bit image is loaded into 24-bit buffer
vbitcount = 24
End If

' Allocate space for an image
rcode = allocimage(tmpimage, bdat.biWidth, bdat.biHeight, vbitcount)
If (rcode <> NO_ERROR) Then
MsgBox "Not enough memory", 0, "Error encountered!"
Exit Sub
End If

' Load image
rcode = loadbmp(bmp_fname, tmpimage)
If (rcode <> NO_ERROR) Then
freeimage tmpimage ' Free image on error
MsgBox "Cannot load file", 0, "Error encountered!"
Exit Sub
End If

If (vbitcount = 1) Then ' If we loaded a 1-bit image, convert to 8-bit grayscale
' because jpeg only supports 8-bit grayscale or 24-bit color images
rcode = allocimage(tmp2image, bdat.biWidth, bdat.biHeight, 8)
If (rcode = NO_ERROR) Then
rcode = convert1bitto8bit(tmpimage, tmp2image)
freeimage tmpimage ' Replace 1-bit image with grayscale image
copyimgdes tmp2image, tmpimage
End If
End If

' Save image
rcode = savejpg(jpg_fname, tmpimage, quality)
freeimage tmpimage

End Sub

........... Add these defines and declarations to your Global module ...........
' Image descriptor
Type imgdes
ibuff As Long
stx As Long
sty As Long
endx As Long
endy As Long
buffwidth As Long
palette As Long
colors As Long
imgtype As Long
bmh As Long
hBitmap As Long
End Type

Type BITMAPINFOHEADER
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type

Declare Function bmpinfo Lib "VIC32.DLL" (ByVal Fname As String, bdat As BITMAPINFOHEADER) As Long
Declare Function allocimage Lib "VIC32.DLL" (image As imgdes, ByVal wid As Long, ByVal leng As Long, ByVal BPPixel As Long) As Long
Declare Function loadbmp Lib "VIC32.DLL" (ByVal Fname As String, desimg As imgdes) As Long
Declare Sub freeimage Lib "VIC32.DLL" (image As imgdes)
Declare Function convert1bitto8bit Lib "VIC32.DLL" (srcimg As imgdes, desimg As imgdes) As Long
Declare Sub copyimgdes Lib "VIC32.DLL" (srcimg As imgdes, desimg As imgdes)
Declare Function savejpg Lib "VIC32.DLL" (ByVal Fname As String, srcimg As imgdes, ByVal quality As Long) As Long

《图像处理----做一个自己的photoshop》
大部分都是源码,其中有bmp<-->jgep<-->GIF的代码.
参考技术A

1、如何从BMP图片读取每个像素,然后根据PNG图片的格式以及RGB色彩算法,将BMP像素转换成png图片,最后根据PNG格式输出到文件。

例程:

FILE *fp = NULL;
char buf[PNG_BYTES_TO_CHECK];
LPSTR lpszFileName = lpszPathName;
if(!lpszFileName) return false;
//打开PNG文件
if(NULL == (fp = fopen(lpszFileName,"rb")))

delete []lpszFileName;
lpszFileName = NULL;
return false;

//验证是否为PNG文件
if(fread(buf,1,PNG_BYTES_TO_CHECK,fp) != PNG_BYTES_TO_CHECK)

fclose(fp);
delete []lpszFileName;
lpszFileName = NULL;
return false;

if( 0 != png_sig_cmp((unsigned char*)buf,(png_size_t)0,PNG_BYTES_TO_CHECK))

fclose(fp);
delete []lpszFileName;
lpszFileName = NULL;
return false;

//以下代码读取PNG文件
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
unsigned int sig_read = PNG_BYTES_TO_CHECK;
int color_type = 0,interlace_type = 0;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
if( NULL == png_ptr)

fclose(fp);
delete []lpszFileName;
lpszFileName = NULL;
return false;

info_ptr = png_create_info_struct(png_ptr);
if(NULL == info_ptr)

 fclose(fp);
 png_destroy_read_struct(&png_ptr,&info_ptr,png_infopp_NULL);
 delete []lpszFileName;
 lpszFileName = NULL;
 return false;

png_init_io(png_ptr,fp);
png_set_sig_bytes(png_ptr,sig_read);
png_read_info(png_ptr,info_ptr);
if(info_ptr->bit_depth == 16)png_set_strip_16(png_ptr);
if(info_ptr->color_type == PNG_COLOR_TYPE_GRAY && info_ptr->pixel_depth < 8)
      png_set_gray_1_2_4_to_8(png_ptr);
switch (info_ptr->pixel_depth)

case 32:
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)png_set_bgr(png_ptr);
png_set_invert_alpha(png_ptr);
//当为32位图像是应该如何处理,例如
//pDib->CreateDIB(info_ptr->width, info_ptr->height,32);
break;
case 24:

png_color_16 my_background=0,255,255,255,0;
png_set_background(png_ptr,&my_background,
PNG_BACKGROUND_GAMMA_SCREEN,0,1.0);
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)png_set_bgr(png_ptr);
//当为32位图像是应该如何处理,例如
//pDib->CreateDIB(info_ptr->width, info_ptr->height,24);

break;
case 8:
case 4:
//当为32位图像是应该如何处理,例如
//if(info_ptr->num_palette>0)
//
// DWORD *pRQ=new DWORD[info_ptr->num_palette];
// for(int i=0;i<info_ptr->num_palette;i++)
// 
// pRQ[i]=RGB(info_ptr->palette[i].red,info_ptr->palette[i].green,info_ptr->palette[i].blue);
// 
// pDib->CreateDIB(info_ptr->width, info_ptr->height,info_ptr->pixel_depth,pRQ,info_ptr->num_palette);
// delete[] pRQ;
//
break;
default:
return false;

png_bytepp  prow_pointers = new png_bytep[info_ptr->height];
UINT nRowBytes = png_get_rowbytes(png_ptr,info_ptr);
UINT row;
for(row=0;row<info_ptr->height;row++)  
prow_pointers[row]=new BYTE[nRowBytes];
png_read_image(png_ptr,prow_pointers);
png_read_end(png_ptr,info_ptr);
//拷贝转换后的图像数据
for(row=0;row<info_ptr->height;row++)
memcpy(pDib->m_lpImage+(info_ptr->height-row-1)*pDib->m_nByteWidth,
prow_pointers[row],pDib->m_nByteWidth);

2、更简单的方法:用windows自带的图片和传真查看器打开要转换的图片,点击右下角的保存按钮,弹出保存对话框,选择要保存的类型。笔者经实验可转换的类型为gif,bmp,png,jpg.最大的优点是方便且不失。

参考技术B 查找关于图像的函数。
VB.NET的话是IMAGE类下面有相关的类来实现。

cximage功能简介

CxImage是一个可以用于MFC 的C++图像处理类库类,它可以打开,保存,显示,转换各种常见格式的图像文件,比如BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K 等格式的文件。可以实现BMP<->JPG,PNG <>TIFF格式等等的互相转换。

  CxImage不仅可以实现图像文件的类型转换,还可以实现在内存图像数据的类型转换,并且使用很方便。除了文件格式的相互转换,它还提供了很多很多图像后处理的功能,比如图像模糊,锐化等等,功能非常强大和实用。

 

示例: 如何转换一种格式到另外一种格式 

 

[cpp] view plain copy
 
  1. CxImage  image;  
  2. // bmp -> jpg   
  3. image.Load( " image.bmp " , CXIMAGE_FORMAT_BMP);  
  4. if (image.IsValid()){  
  5.      if ( ! image.IsGrayScale()) image.IncreaseBpp( 24 );  
  6.     image.SetJpegQuality( 80 );  
  7.     image.Save( " image.jpg " ,CXIMAGE_FORMAT_JPG);  
  8. }  
  9. // png -> tif   
  10. image.Load( " image.png " , CXIMAGE_FORMAT_PNG);  
  11. if (image.IsValid()){  
  12.     image.Save( " image.tif " ,CXIMAGE_FORMAT_TIF);  
  13. }   

 

 

  如何从资源中加载图像

[cpp] view plain copy
 
  1. // Load the resource IDR_PNG1 from the PNG resource type   
  2. CxImage * newImage = new CxImage();  
  3. newImage -> LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDR_PNG1),  
  4.                        " PNG " ),CXIMAGE_FORMAT_PNG);  
  5. 或者  
  6. // Load the resource IDR_JPG1 from DLL   
  7. CxImage * newImage = new CxImage();  
  8. HINSTANCE hdll = LoadLibrary( " imagelib.dll " );  
  9. if (hdll){  
  10.     HRSRC hres = FindResource(hdll,MAKEINTRESOURCE(IDR_JPG1), " JPG " );  
  11.     newImage -> LoadResource(hres,CXIMAGE_FORMAT_JPG,hdll);  
  12.     FreeLibrary(hdll);  
  13. }  
  14. 或者  
  15. // Load a bitmap resource;   
  16. HBITMAP bitmap = ::LoadBitmap(AfxGetInstanceHandle(),  
  17.                            MAKEINTRESOURCE(IDB_BITMAP1)));  
  18. CxImage * newImage = new CxImage();  
  19. newImage -> CreateFromHBITMAP(bitmap);   


如何解码内存中的图像 

 

[cpp] view plain copy
 
  1. CxImage image((BYTE * )buffer,size,image_type);  
  2. 或者  
  3. CxMemFile memfile((BYTE * )buffer,size);  
  4. CxImage image( & memfile,image_type);  
  5. 或者  
  6. CxMemFile memfile((BYTE * )buffer,size);  
  7. CxImage * image = new CxImage();  
  8. image -> Decode( & memfile,type);   


 如何对内存中的图像编码 

 

 

[cpp] view plain copy
 
  1. long size = 0 ;  
  2. BYTE * buffer = 0 ;  
  3. image.Encode(buffer,size,image_type);  
  4. ...  
  5. image.FreeMemory(buffer);  
  6. 或者  
  7. CxMemFile memfile;  
  8. memfile.Open();  
  9. image.Encode( & memfile,image_type);  
  10. BYTE * buffer = memfile.GetBuffer();  
  11. long size = memfile.Size();  
  12. ...  
  13. image.FreeMemory(buffer);   


 

  如何创建一副多页的TIFF

[cpp] view plain copy
 
  1. CxImage * pimage[ 3 ];  
  2. pimage[ 0 ] =& image1;  
  3. pimage[ 1 ] =& image2;  
  4. pimage[ 2 ] =& image3;  
  5. FILE * hFile;  
  6. hFile = fopen( " multipage.tif " , " w+b " );  
  7. CxImageTIF multiimage;  
  8. multiimage.Encode(hFile,pimage, 3 );  
  9. fclose(hFile);  
  10. 或者  
  11. FILE * hFile;  
  12. hFile = fopen( " c://multi.tif " , " w+b " );  
  13. CxImageTIF image;  
  14. image.Load( " c://1.tif " ,CXIMAGE_FORMAT_TIF);  
  15. image.Encode(hFile, true );  
  16. image.Load( " c://2.bmp " ,CXIMAGE_FORMAT_BMP);  
  17. image.Encode(hFile, true );  
  18. image.Load( " c://3.png " ,CXIMAGE_FORMAT_PNG);  
  19. image.Encode(hFile);  
  20. fclose(hFile);   


如何复制和粘贴图像

 

[cpp] view plain copy
 
  1. // 复制(copy)   
  2. HANDLE hDIB = image -> CopyToHandle();  
  3. if (::OpenClipboard(AfxGetApp() -> m_pMainWnd -> GetSafeHwnd())) {  
  4.      if (::EmptyClipboard()) {  
  5.          if (::SetClipboardData(CF_DIB,hDIB) == NULL ) {  
  6.             AfxMessageBox( " Unable to set Clipboard data " );  
  7. }    }    }  
  8. CloseClipboard();  
  9. // 粘贴(paste)   
  10. HANDLE hBitmap = NULL;  
  11. CxImage * newima = new CxImage();  
  12. if (OpenClipboard()) hBitmap = GetClipboardData(CF_DIB);  
  13. if (hBitmap) newima -> CreateFromHANDLE(hBitmap);  
  14. CloseClipboard();   

 

 

  如何在图片框控件(Picture Box)中显示图像 

[cpp] view plain copy
 
  1. HBITMAP m_bitmap = NULL;  
  2. CxImage image( " myfile.png " , CXIMAGE_FORMAT_PNG);  
  3. ...  
  4. CDC * hdc = m_picture.GetDC();  
  5. HBITMAP m_bitmap = image.MakeBitmap(hdc -> m_hDC);  
  6. HBITMAP hOldBmp = m_picture.SetBitmap(m_bitmap);  
  7. if (hOldBmp) DeleteObject(hOldBmp);  
  8. if (hdc -> m_hDC) m_picture.ReleaseDC(hdc);  
  9. ...  
  10. if (m_bitmap) DeleteObject(m_bitmap);   


Cimage合并图片就是这么简单: 

[cpp] view plain copy
 
  1. CxImage t_img1,t_img2,t_img3;   
  2.   
  3.       int t_h1,t_w1,t_h2,t_w2,t_h3,t_w3,t_bpp;   
  4.   
  5.       t_img1.Load("F://1.jpg");   
  6.   
  7.       t_img2.Load("F://2.jpg");   
  8.   
  9.       t_h1=t_img1.GetHeight();   
  10.   
  11.       t_w1=t_img1.GetWidth();   
  12.   
  13.       t_h2=t_img2.GetHeight();   
  14.   
  15.       t_w2=t_img2.GetWidth();   
  16.   
  17.       t_h3=t_h1;   
  18.   
  19.       t_w3=t_w1+t_w2;   
  20.   
  21.       t_bpp=t_img1.GetBpp();   
  22.   
  23.       t_img3.Create(t_w3,t_h3,t_bpp);   
  24.   
  25.       t_img3.MixFrom(t_img1,0,0);   
  26.   
  27.       t_img3.MixFrom(t_img2,t_w1,0);   
  28.   
  29.       t_img3.Save("f://3.jpg",CXIMAGE_FORMAT_JPG);   


译后序:

  关于图像处理库,我相信大家有一个共同的疑问:这么多图像处理库,我该如何选择?在CSDN的blog中有这样一段文字,比较透彻地回答了这个问题,感谢作者的透彻解释:

  "CxImage类库是一个优秀的图像操作类库。它可以快捷地存取、显示、转换各种图像。有的读者可能说,有那么多优秀的图形库,如OpenIL,FreeImage, PaintLib等等,它们可谓是功能强大,齐全,没必要用其它的类库。但我要说,这些类库基本上没有免费的,使用这些类库,你要被这样那样的许可协议所束缚。

  在这点上,CxImage类库是完全免费的。另外,在使用上述类库时,你会遇到重重麻烦。因为它们大部分是平台无关的,且用C语言写成,有的还夹杂着基本的C++ wrapper和成堆德编译选项的声明需要你去处理。而CxImage类库在这方面做得很好。还有让我最看好的,就是作者完全公开了源代码。相对于那些封装好的图形库和GDI+来说,这一点使我们可以进一步学习各种编解码技术,而不再浮于各种技术的表面。"

 

以上是关于bmp格式转换PNG格式 c语言或c++编程的主要内容,如果未能解决你的问题,请参考以下文章

如何将png格式、jpg格式的图片转成24bit的bmp图片。

图片怎么转png格式

C语言实现BMP格式转RGB格式YUV格式

以编程方式为 Silverlight 显示选择图像转换格式为 JPEG 或 PNG

C语言实现RGB888转BMP格式图片功能

php转换bmp图片格式为jpg格式