【原图是8位BMP,用Cimage保存后变成了32位,图片太大!如何保存成8位而且不失真?】

ArahatAthersata 2017-12-24 04:52:45
  我把几十个8位图在内存DC里拼成了一张大图,用Cimage保存后变成32位,体积太大!GDI竟连保持原图位深的功能都没有?请教怎样保存成8位而且不失真?? 最简单的方法是什么??
...全文
683 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2017-12-27
  • 打赏
  • 举报
回复
为什么要用 CImage,直接用 Windows 的 GDI API 去拼接,最后还是得到一个 HBITMAP,将 HBITMAP 中的信息保存为 bmp 文件,代码网上很多。
smwhotjay 2017-12-27
  • 打赏
  • 举报
回复
8位应该也ok吧,你找个hdc保存bmp 8位的代码即可。
赵4老师 2017-12-26
  • 打赏
  • 举报
回复
谁操作调色板,竟然可以不“间接或直接调用1楼给出的调色板相关API或写一段类似其功能的代码”?!
schlafenhamster 2017-12-26
  • 打赏
  • 举报
回复
"可以无损还原成8位图" 不保证 !
schlafenhamster 2017-12-25
  • 打赏
  • 举报
回复
给·一个·直接文件处理的

void CPartialBitmapView::MergePartialBmp(char *MergeFile,char *MergedFile)
{
// 1st get MergedFile's bits.
	FILE *bmpDst=0;
	bmpDst=fopen(MergedFile,"rb");
	if(!bmpDst)
	{
		AfxMessageBox("MergedFile Lost!");
		CreateEmptyMergedFile(MergedFile);
	}
// reopen
	bmpDst=fopen(MergedFile,"rb");
	fseek(bmpDst,0L,SEEK_END);
	LONG filelenDst=ftell(bmpDst);
	fseek(bmpDst,0L,SEEK_SET);
	BYTE *bufferDst=new BYTE[filelenDst];
	fread(bufferDst,sizeof(char),filelenDst,bmpDst);
	fclose(bmpDst);
//
	LPBITMAPFILEHEADER pBMPfileDst=(LPBITMAPFILEHEADER) bufferDst;
	LPBITMAPINFOHEADER pBMPinfoDst=(LPBITMAPINFOHEADER) (bufferDst+sizeof(BITMAPFILEHEADER)); 
	int colord=0;//
	if(pBMPinfoDst->biBitCount==8)
	{
		colord=256;
	}
// width height and bits
	WORD widDst=(WORD)pBMPinfoDst->biWidth;// 640
	WORD heiDst=(WORD)pBMPinfoDst->biHeight;// 480
	BYTE *bitsDstAt=bufferDst+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colord*sizeof(RGBQUAD);//=4;
	RGBQUAD *rgbDst=(RGBQUAD*)(bufferDst+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
//// 2nd get MergeFile's bits. ///////////////////////////////////////////////
	FILE *bmpSrc=0;
	bmpSrc=fopen(MergeFile,"rb");
	if(!bmpSrc)
	{// check "tmp.bmp"
		AfxMessageBox("No Source file!");
		SavePartialBmp(m_Tracker.m_rect.left,m_Tracker.m_rect.top,m_Tracker.m_rect.right,
						m_Tracker.m_rect.bottom);
	}
// reopen 
	bmpSrc=fopen(MergeFile,"rb");
	fseek(bmpSrc,0L,SEEK_END);
	LONG filelenSrc=ftell(bmpSrc);// 17462
	fseek(bmpSrc,0L,SEEK_SET);
	BYTE *bufferSrc=new BYTE[filelenSrc];
	fread(bufferSrc,sizeof(char),filelenSrc,bmpSrc);
	fclose(bmpSrc);
	LPBITMAPFILEHEADER pBMPfileSrc=(LPBITMAPFILEHEADER) bufferSrc;
	LPBITMAPINFOHEADER pBMPinfoSrc=(LPBITMAPINFOHEADER) (bufferSrc+sizeof(BITMAPFILEHEADER)); 
// merging pos
    int Xstart=pBMPfileSrc->bfReserved1;
    int Ystart=pBMPfileSrc->bfReserved2; 
//afxDump << Xstart << ";" << Ystart << "\n";// 256;192
	int colors=0;//
	if(pBMPinfoSrc->biBitCount==8)
	{
		colors=256;
	}
	WORD widSrc=(WORD)pBMPinfoSrc->biWidth;// 128
	WORD heiSrc=(WORD)pBMPinfoSrc->biHeight;// 128
	WORD Xend=Xstart+widSrc;
	WORD Yend=Ystart+heiSrc;
//afxDump << Xend << ";" << Yend << "\n";// 384;320
	BYTE *bitsSrcAt=bufferSrc+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colors*sizeof(RGBQUAD);
// Pallete
	RGBQUAD *rgbSrc=(RGBQUAD*)(bufferSrc+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
// copy Pallete
	if(colors==256)
	{
		memcpy(rgbDst,rgbSrc,colors*sizeof(RGBQUAD));
	}
	int BPP=pBMPinfoDst->biBitCount/8;
// now copy bits
	for(int hei=Yend-1;hei >= Ystart;hei--)// vertical flip
	{//
		for(int wid=Xstart;wid < Xend;wid++)
		{
//          bitsDstAt[ (heiDst-hei-1)*widDst+wid]     =bitsSrcAt[ (heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart)];//
			bitsDstAt[((heiDst-1-hei)*widDst+wid)*BPP]=bitsSrcAt[((heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart))*BPP];//
			if(BPP>=3)
			{// 24 
				bitsDstAt[((heiDst-1-hei)*widDst+wid)*BPP+1]=bitsSrcAt[((heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart))*BPP+1];//
				bitsDstAt[((heiDst-1-hei)*widDst+wid)*BPP+2]=bitsSrcAt[((heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart))*BPP+2];//
			}
			if(BPP==4)
				bitsDstAt[((heiDst-1-hei)*widDst+wid)*BPP+3]=bitsSrcAt[((heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart))*BPP+3];//
		}
	}
// write back
	bmpDst=fopen(MergedFile,"wb");
	fwrite(bufferDst,1,filelenDst,bmpDst);
	fclose(bmpDst);
//
	if(bufferSrc) delete [] bufferSrc;
	if(bufferDst) delete [] bufferDst;
//
	AfxMessageBox("Bmp Merged!");
}
1 被merge的文件的位置在 // merging pos int Xstart=pBMPfileSrc->bfReserved1; int Ystart=pBMPfileSrc->bfReserved2; 2 那个包含所有 merge 文件本身 必须 先创建(足够大,带调色板)
ArahatAthersata 2017-12-25
  • 打赏
  • 举报
回复
引用 8 楼 zhao4zhong1 的回复:
如果楼主不间接或直接调用1楼给出的调色板相关API或写一段类似其功能的代码,我把头给你!
这些API确实用不上,我现在想到的办法是把这个32位的图片用原来的调色板还原成8位,因为这个32位图是从8位转换的,所以颜色数不超过256种,那么完全可以无损还原成8位图吧?难道论坛的老前辈们还不如我这个后辈的点子多?应该是都藏着掖着怕别人学会吧
赵4老师 2017-12-25
  • 打赏
  • 举报
回复
如果楼主不间接或直接调用1楼给出的调色板相关API或写一段类似其功能的代码,我把头给你!
ArahatAthersata 2017-12-25
  • 打赏
  • 举报
回复
引用 6 楼 schlafenhamster 的回复:
给·一个·直接文件处理的

void CPartialBitmapView::MergePartialBmp(char *MergeFile,char *MergedFile)
{
// 1st get MergedFile's bits.
	FILE *bmpDst=0;
	bmpDst=fopen(MergedFile,"rb");
	if(!bmpDst)
	{
		AfxMessageBox("MergedFile Lost!");
		CreateEmptyMergedFile(MergedFile);
	}
// reopen
	bmpDst=fopen(MergedFile,"rb");
	fseek(bmpDst,0L,SEEK_END);
	LONG filelenDst=ftell(bmpDst);
	fseek(bmpDst,0L,SEEK_SET);
	BYTE *bufferDst=new BYTE[filelenDst];
	fread(bufferDst,sizeof(char),filelenDst,bmpDst);
	fclose(bmpDst);
//
	LPBITMAPFILEHEADER pBMPfileDst=(LPBITMAPFILEHEADER) bufferDst;
	LPBITMAPINFOHEADER pBMPinfoDst=(LPBITMAPINFOHEADER) (bufferDst+sizeof(BITMAPFILEHEADER)); 
	int colord=0;//
	if(pBMPinfoDst->biBitCount==8)
	{
		colord=256;
	}
// width height and bits
	WORD widDst=(WORD)pBMPinfoDst->biWidth;// 640
	WORD heiDst=(WORD)pBMPinfoDst->biHeight;// 480
	BYTE *bitsDstAt=bufferDst+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colord*sizeof(RGBQUAD);//=4;
	RGBQUAD *rgbDst=(RGBQUAD*)(bufferDst+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
//// 2nd get MergeFile's bits. ///////////////////////////////////////////////
	FILE *bmpSrc=0;
	bmpSrc=fopen(MergeFile,"rb");
	if(!bmpSrc)
	{// check "tmp.bmp"
		AfxMessageBox("No Source file!");
		SavePartialBmp(m_Tracker.m_rect.left,m_Tracker.m_rect.top,m_Tracker.m_rect.right,
						m_Tracker.m_rect.bottom);
	}
// reopen 
	bmpSrc=fopen(MergeFile,"rb");
	fseek(bmpSrc,0L,SEEK_END);
	LONG filelenSrc=ftell(bmpSrc);// 17462
	fseek(bmpSrc,0L,SEEK_SET);
	BYTE *bufferSrc=new BYTE[filelenSrc];
	fread(bufferSrc,sizeof(char),filelenSrc,bmpSrc);
	fclose(bmpSrc);
	LPBITMAPFILEHEADER pBMPfileSrc=(LPBITMAPFILEHEADER) bufferSrc;
	LPBITMAPINFOHEADER pBMPinfoSrc=(LPBITMAPINFOHEADER) (bufferSrc+sizeof(BITMAPFILEHEADER)); 
// merging pos
    int Xstart=pBMPfileSrc->bfReserved1;
    int Ystart=pBMPfileSrc->bfReserved2; 
//afxDump << Xstart << ";" << Ystart << "\n";// 256;192
	int colors=0;//
	if(pBMPinfoSrc->biBitCount==8)
	{
		colors=256;
	}
	WORD widSrc=(WORD)pBMPinfoSrc->biWidth;// 128
	WORD heiSrc=(WORD)pBMPinfoSrc->biHeight;// 128
	WORD Xend=Xstart+widSrc;
	WORD Yend=Ystart+heiSrc;
//afxDump << Xend << ";" << Yend << "\n";// 384;320
	BYTE *bitsSrcAt=bufferSrc+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colors*sizeof(RGBQUAD);
// Pallete
	RGBQUAD *rgbSrc=(RGBQUAD*)(bufferSrc+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
// copy Pallete
	if(colors==256)
	{
		memcpy(rgbDst,rgbSrc,colors*sizeof(RGBQUAD));
	}
	int BPP=pBMPinfoDst->biBitCount/8;
// now copy bits
	for(int hei=Yend-1;hei >= Ystart;hei--)// vertical flip
	{//
		for(int wid=Xstart;wid < Xend;wid++)
		{
//          bitsDstAt[ (heiDst-hei-1)*widDst+wid]     =bitsSrcAt[ (heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart)];//
			bitsDstAt[((heiDst-1-hei)*widDst+wid)*BPP]=bitsSrcAt[((heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart))*BPP];//
			if(BPP>=3)
			{// 24 
				bitsDstAt[((heiDst-1-hei)*widDst+wid)*BPP+1]=bitsSrcAt[((heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart))*BPP+1];//
				bitsDstAt[((heiDst-1-hei)*widDst+wid)*BPP+2]=bitsSrcAt[((heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart))*BPP+2];//
			}
			if(BPP==4)
				bitsDstAt[((heiDst-1-hei)*widDst+wid)*BPP+3]=bitsSrcAt[((heiSrc-1-(hei-Ystart))*widSrc+(wid-Xstart))*BPP+3];//
		}
	}
// write back
	bmpDst=fopen(MergedFile,"wb");
	fwrite(bufferDst,1,filelenDst,bmpDst);
	fclose(bmpDst);
//
	if(bufferSrc) delete [] bufferSrc;
	if(bufferDst) delete [] bufferDst;
//
	AfxMessageBox("Bmp Merged!");
}
1 被merge的文件的位置在 // merging pos int Xstart=pBMPfileSrc->bfReserved1; int Ystart=pBMPfileSrc->bfReserved2; 2 那个包含所有 merge 文件本身 必须 先创建(足够大,带调色板)
我是把几张8位图通过LoadImage加载,再画到内存DC上拼接成一张大图的,有没有办法在我现有的基础上保存成8位图?
schlafenhamster 2017-12-24
  • 打赏
  • 举报
回复
用· bmp 文件·拼接·不可能·变 32 位的 你是 用 CDC 拼接 的 ?
ArahatAthersata 2017-12-24
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
可能·拼接·时已经是 32 位了, 先 拼一个看看。
如果能保存成8位,我就不来问了
schlafenhamster 2017-12-24
  • 打赏
  • 举报
回复
可能·拼接·时已经是 32 位了, 先 拼一个看看。
ArahatAthersata 2017-12-24
  • 打赏
  • 举报
回复
引用 1 楼 zhao4zhong1 的回复:
Color Functions The following functions are used with color. AnimatePalette CreateHalftonePalette CreatePalette GetColorAdjustment GetNearestColor GetNearestPaletteIndex GetPaletteEntries GetSystemPaletteEntries GetSystemPaletteUse HTUI_ColorAdjustment HTUI_DeviceColorAdjustment RealizePalette ResizePalette SelectPalette SetColorAdjustment SetPaletteEntries SetSystemPaletteUse UnrealizeObject UpdateColors
我只想把位图按原始8位无损输出罢了,这么麻烦?
赵4老师 2017-12-24
  • 打赏
  • 举报
回复
Color Functions The following functions are used with color. AnimatePalette CreateHalftonePalette CreatePalette GetColorAdjustment GetNearestColor GetNearestPaletteIndex GetPaletteEntries GetSystemPaletteEntries GetSystemPaletteUse HTUI_ColorAdjustment HTUI_DeviceColorAdjustment RealizePalette ResizePalette SelectPalette SetColorAdjustment SetPaletteEntries SetSystemPaletteUse UnrealizeObject UpdateColors

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧