将1bpp的bmp图像存储为1bpp或者2bpp的tiff格式

将1bpp的bmp图像存储为1bpp或者2bpp的tiff格式将 1bpp 的位图转换为 1bit 2bittiff 参数 BYTE src 二值图像的像素数据 不包含头部信息 1bpp intsrc width 原图的宽度 inpixles intsrc height 原图

大家好,欢迎来到IT知识分享网。

// 将1bpp的位图转换为 1bit/2bit tiff / 参数: BYTE *src 二值图像的像素数据,不包含头部信息, 1bpp, int src_width 原图的宽度, in pixles, int src_height 原图的高度, in pixles int bpp 转换tiff指定的bpp */ static BYTE * BW2Tif(BYTE *src, int src_width, int src_height, int bpp, DWORD& totalSize) { int dst_width = (bpp == 1) ? src_width : src_width/2; int dst_height = src_height; // get src and dst scan width int src_pitch = (src_width + 7)/8 + 3 & ~3; int dst_pitch = (dst_width * bpp + 31)/32*4; // get src and dst size unsigned int tif_size, bmp_size; if(0x & dst_height) { bmp_size= src_pitch*(0 - src_height); tif_size = dst_pitch*(0 - dst_height); } else{ bmp_size = src_pitch*src_height; tif_size = dst_pitch*dst_height; } // Image File Header const unsigned char tif_ifh[10]={ 'I','I', //intel顺序 0x2a,0x00, //tiff版本号 0x08,0x00,0x00,0x00, //IFD(图形文卷目录 Image File Diretory)偏移, 8个字节 0x0F,0x00, // 这两个字节属于IFD了,指定有多少个Directory Entry }; // Directory Entry ,每个都是12个字节的 , TIFF 6.0规定,标签要以升序的方式排列 unsigned long tif_ifd[0x0f*3+4]={ 0x000400FE, 0x01, 0x000, // NewSubfileType, 0x00030100, 0x01, 0x018, // ImageWidth,The number of columns in the image, i.e., the number of pixels per scanline 0x00030101, 0x01, 0x018, // ImageLength, The number of rows (sometimes described as scanlines) in the image. 0x00030102, 0x01, bpp, // BitPerSample 258 0x00030103, 0x01, 0x001, // Compression, 1无压缩 0x00030106, 0x01, 0x000, // PhotometricInterpretation, 对于bilevel图像,值0=WhiteIsZero,1=BlackIsZero 0x00040111, 0x01, 0x0CE, // StripOffsets,For each strip, the byte offset of that strip, // N = StripsPerImage for PlanarConfiguration equal to 1; // N = SamplesPerPixel * StripsPerImage for PlanarConfiguration equal to 2 // 从字面上看来, StripOffsets是个数组,小于64kb, 这里是0xce, 就是头部的206个字节了 0x00030112, 0x01, 0x001, // Orientation 0x00030115, 0x01, 0x001, // SamplesPerPixel 0x00030116, 0x01, 0xffff, // RowsPerStrip, The number of rows in each strip (except possibly the last strip.) // RowsPerStrip and ImageLength together tell us the number of strips in the entire image. default is 2^32-1, 推荐每个strip是8k数据 // image. The equation is: StripsPerImage= floor ((ImageLength + RowsPerStrip - 1) / RowsPerStrip). 0x00040117, 0x01, 0x07F, // StripByteCounts 0x0005011A, 0x01, 0x0BE, // XResolution 0x0005011B, 0x01, 0x0C6, // YResolution 0x0003011C, 0x01, 0x001, // PlanarConfiguration , 1是单平面格式, 2多平面格式 0x00030128, 0x01, 0x002, // ResolutionUnit, 0x002 = inch 0x, 0x0, // X分辨率ofset=164 0x, 0x0, // Y分辨率ofset=16C }; // tif_ifd[ 5] = dst_width; tif_ifd[ 8] = dst_height; tif_ifd[29] = (tif_size + 0x0f) & 0xfffffff0; // 简单的做成一个strip tif_ifd[32] = tif_size; // allocate dst image hpgl unsigned int total_size = sizeof(tif_ifh) + sizeof(tif_ifd) + tif_size; TRACE1("tiff size=0x%x\n", sizeof(tif_ifh) + sizeof(tif_ifd)); BYTE *dst = new BYTE[total_size]; if(NULL == dst) return FALSE; BYTE *curr = dst; totalSize = total_size; // memcpy(curr, tif_ifh, sizeof(tif_ifh)); curr += sizeof(tif_ifh); memcpy(curr, tif_ifd, sizeof(tif_ifd)); curr += sizeof(tif_ifd); // 当src图像的宽度是整数个字节的时候,可以直接复制数据,如果多出几个bit,就不好搞了 //memcpy(curr, src, tif_size); // gray2bmp_to_tif.c 中程序,是把每个像素用一个字节来存储了,而这里不是的 // 所以不能照着写程序了 int width_align = src_width & 0xffffFFF8; int nBytes = width_align/8; if (src_width - width_align) // 有边角bit位 nBytes += 1; LPBYTE src2 = src; LPBYTE dst2 = curr; int x,y; for (y = 0; y < src_height; y++) { src2 = src + y * src_pitch; dst2 = curr + y * nBytes; //写入tiff的数据流,不要自己补充空白数据 memcpy(dst2, src2, nBytes); src2 += nBytes; dst2 += nBytes; } return dst; } // 这个是测试代码 void CPagePt::OnBnClickedButtonCv() { CFileDialog fd(TRUE, _T("bmp"), NULL, NULL, _T("All files(*.*)|*.*|Wibdows Bitmap(*.bmp)|*.bmp||")); if(fd.DoModal() != IDOK) return; CString filename = fd.GetPathName(); HBITMAP hImage = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION|LR_DEFAULTSIZE); //CBitmap* m_Bitmap = CBitmap::FromHandle(hImage); BITMAP bm; //获取位图信息 GetObject(hImage, sizeof(BITMAP), &bm); // Sumit: memory allocation is still 1800x1800 in your code.. BYTE* bmpBuffer=(BYTE*)bm.bmBits; // GlobalAlloc(GPTR, bm.bmWidthBytes * bm.bmHeight); //allocate memory DWORD tifSize; BYTE *tif = BW2Tif(bmpBuffer, bm.bmWidth, bm.bmHeight, 2, tifSize); CFile cf("C:\\bw2tif_out.tif", CFile::modeCreate | CFile::modeWrite); cf.Write(tif, tifSize); cf.Close(); delete tif; } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/146605.html

(0)
上一篇 2025-04-13 16:10
下一篇 2025-04-13 16:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信