首页 > 其他分享 >将1bpp的bmp图像存储为1bpp或者2bpp的tiff格式

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

时间:2022-12-13 16:05:33浏览次数:33  
标签:src int tiff dst 0x01 2bpp tif 1bpp size




// 将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(0x80000000 & 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

0x60031280, 0x01000000, // X分辨率ofset=164
0x60031280, 0x01000000, // 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;

}



标签:src,int,tiff,dst,0x01,2bpp,tif,1bpp,size
From: https://blog.51cto.com/u_15911341/5934362

相关文章

  • Ubuntu 14.04 iNode Client找不到库libjpeg和libtiff的解决方法
    iNodeClient在Ubuntu10.04时,直接运行install.sh后便安装成功。在Ubuntu14.04的版本,安装后双击iNodeClient后却无法运行。重装后问题依旧。于是使用命令行来运行。提示......
  • H5文件保存为TIFF
    上周一个朋友拜托我帮它处理下遥感数据,拿到手一看,发现文件格式.h5,但是以往接触的遥感数据格式基本为.tif,带着好奇上网查了一下,维基百科对它的解释:HDF:层级数据格式(Hiera......
  • mapboxgl加载tiff
    缘起近期在项目中遇到这么一个需求,需要在地图上展示一组格网数据,格网大小为2m*2m,地图api用的mapboxgl。起初拿到这个需要感觉很easy,在地图上添加一个fill图层就好啦。把格......
  • .tiff后缀的文件
    https://baike.baidu.com/item/TIFF/2106?fromtitle=TIFF%E6%A0%BC%E5%BC%8F&fromid=3463194&fr=aladdin标签图像文件格式(TagImageFileFormat,TIFF)是一种灵活的位图格式......
  • 判断图片格式的代码(判断jpg,png,gif,tiff)
    load=function(path){//varfullpath=..io.exist(path)//if(fullpath)returndll.ImageLoadW(owner.hImage,fullpath);varbuffer=..string.loadBuf......
  • Java 解析Tiff深入研究
        最近在读取客户发过来的tiff文件是,底层竟然报错了,错误:bandOffsets.lengthiswrong!  没办法,因为错误消息出现在tiff的read中,因此就对底层序中tiff读取的代......
  • xarray 生成 tiff 文件
    生成tiff文件fromeccodesimport*importnumpyasnpimportxarrayasxrimportrioxarrayasriot2=xr.Dataset(data_vars={'REF':(['longitude','latit......