将内存图像数据保存为png及tif方法
(2014-05-27 10:56:00)
标签:
bmppngtif |
将内存图像数据保存为png及tif方法
需要将内存中的图像数据保存为tif或者png的格式,就需要用到libpng,libtiff及zlib这三个 库.
工程中需要有png.h , tiff.h, tiffio.h
这几个库都是可以用在windows及linux下的,我在这两个系统下都用的下面的方法,无非就是这两种系统下的c++中字符串及对象类型的处理
具体的方法如下:
保存TIF
-
BOOL
ImgToTIF( LPCTSTRstrFileName, PVOIDpImageData, ULONG_ulWidth, ULONG_ulHeight, ULONGnBit) - {
-
UINT nLen = _tcsclen(strFileName); -
TCHAR strFile[255]; -
TCHAR ext3[4], ext4[5]; -
_tcsnccpy(ext3,strFileName+nLen-4,4); -
_tcsnccpy(ext4,strFileName+nLen-5,5); -
-
LPCTSTR tPFileName = strFileName; -
-
if(_tcsnccmp(ext3,_T(".tif"),4)!=0 && ".TIF"),4)!=0_tcsnccmp(ext3,_T( -
&&_tcsnccmp(ext4,_T(".TIFF"),5)!=0 && ".tiff"),5)!=0)_tcsnccmp(ext4,_T( -
{ -
_tcscpy(strFile,strFileName); -
_tcscpy(strFile+nLen,_T(".tif")); -
tPFileName = strFile; -
} -
-
BOOL result = FALSE; -
-
BOOL b16Bit = nBit/16==0 ? TRUE:FALSE; -
-
int nChannels = b16Bit ? nBit/16:nBit/8; -
-
int depth = b16Bit?16:8; -
-
if( nBit != 0 && nBit%8 != 0 ) -
return FALSE; -
-
PUCHAR imgData PUCHAR)pImageData;= ( -
-
TIFF* tif = NULL; -
#ifdef
UNICODE -
tif = TIFFOpenW( tPFileName, "w" ); -
#else
-
tif = TIFFOpen( tPFileName, "w" ); -
#endif
-
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, _ulWidth); // set the width of the image -
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, _ulHeight); // set the height of the image -
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, nChannels); // set number of channels per pixel -
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, depth); // set the size of the channels -
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); // set the origin of the image. -
// Some other essential fields to set that you do not have to understand for now. -
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); -
uint16 colorMode = nChannels==1 ? PHOTOMETRIC_MINISBLACK:PHOTOMETRIC_RGB; -
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, colorMode); -
uint16 compression = COMPRESSION_NONE;// -
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression); -
-
tsize_t linebytes = nChannels * _ulWidth * depth / 8; // length in memory of one row of pixel in the image. -
-
unsigned char *buf //= NULL; buffer used to store the row of pixel information for writing to file -
-
// Allocating memory to store the pixels of current row -
size_t x = TIFFScanlineSize(tif); -
if (TIFFScanlineSize(tif)==linebytes) -
buf =(unsigned char *)_TIFFmalloc(linebytes); -
else -
buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif)); -
-
// We set the strip size of the file to be size of one row of pixels -
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, nChannels * _ulWidth)); -
-
//Now writing image to the file one strip at a time -
for (uint32 row = 0; row < _ulHeight; row++) -
{ -
memcpy(buf, &imgData[(_ulHeight-row-1)*linebytes], linebytes); // check the index here, and figure out why not using h*linebytes -
if (TIFFWriteScanline(tif, buf, row, 0) < 0) -
break; -
} -
-
TIFFClose(tif); -
if (buf) -
_TIFFfree(buf); -
-
return TRUE; - }
保存PNG:
-
BOOL
ImgToPNG( LPCTSTRstrFileName, PVOIDpImageData, ULONG_ulWidth, ULONG_ulHeight, ULONGnBit) - {
-
UINT nLen = _tcsclen(strFileName); -
TCHAR strFile[255]; -
TCHAR ext3[4], ext4[5]; -
_tcsnccpy(ext3,strFileName+nLen-4,4); -
_tcsnccpy(ext4,strFileName+nLen-5,5); -
-
LPCTSTR tPFileName = strFileName; -
-
if(_tcsnccmp(ext3,_T(".PNG"),4)!=0 && ".png"),4)!=0)_tcsnccmp(ext3,_T( -
{ -
_tcscpy(strFile,strFileName); -
_tcscpy(strFile+nLen,_T(".png")); -
tPFileName = strFile; -
} -
-
char filename[255]; -
#ifdef
UNICODE -
WideCharToMultiByte(CP_ACP, NULL,tPFileName,-1,filename, 255, NULL, NULL); -
#else
-
_tcscpy(filename,tPFileName); -
#endif
-
-
png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); -
png_infop info_ptr = 0; -
FILE* f = 0; -
uchar** buffer = 0; -
PUCHAR imgData PUCHAR)pImageData;= ( -
int y; -
BOOL result = FALSE; -
-
BOOL b16Bit = nBit/16==0 ? TRUE:FALSE; -
-
int nChannels = b16Bit ? nBit/16:nBit/8; -
-
int depth = b16Bit?16:8; -
-
int step = _ulWidth*nChannels*depth/8; -
-
if( nBit != 0 && nBit%8 != 0 ) -
return FALSE; -
-
if( png_ptr ) -
{ -
info_ptr = png_create_info_struct( png_ptr ); -
-
if( info_ptr ) -
{ -
if( setjmp( png_ptr->jmpbuf ) == 0 ) -
{ -
f = fopen( filename, "wb" ); -
-
if( f ) -
{ -
png_init_io( png_ptr, f ); -
-
png_set_compression_mem_level( png_ptr, MAX_MEM_LEVEL ); -
-
png_set_IHDR( png_ptr, info_ptr, _ulWidth, _ulHeight, depth, -
nChannels == 1 ? PNG_COLOR_TYPE_GRAY : -
nChannels == 3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGBA, -
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, -
PNG_FILTER_TYPE_DEFAULT ); -
-
png_write_info( png_ptr, info_ptr ); -
-
png_set_bgr( png_ptr ); -
if( !isBigEndian() ) -
png_set_swap( png_ptr ); -
-
/////////////////////////////////////// -
//png图像内存的上下位置跟具体图像的数据颠倒 -
buffer = new uchar*[_ulHeight]; -
for( y = 0; y < _ulHeight; y++ ) -
buffer[_ulHeight-y-1] = (uchar*)(imgData + y*step); -
-
png_write_image( png_ptr, buffer ); -
png_write_end( png_ptr, info_ptr ); -
-
delete[] buffer; -
-
result = TRUE; -
} -
} -
} -
} -
png_destroy_write_struct( &png_ptr, &info_ptr ); -
-
if(f) fclose( f ); -
-
return result; - }
摘自http://blog.csdn.net/tiantangxingkong/article/details/6715328#