用到的数据结构如下:
-
-
structRectItem
- {
-
unsignedintx;
-
unsignedinty;
-
unsignedintwidth;
-
unsignedintheight;
- };
-
-
structImageItem
- {
-
unsignedintid;
-
unsignedintx;
-
unsignedinty;
-
charfilename[256];
-
BITMAPbmp;
-
HBITMAPhbmp;
- };
-
-
classImageList
- {
-
public:
-
voidInsert(CStringstrPath);
- ImageList();
- ~ImageList();
-
intGetMaxHeight();
-
intGetMaxWidth();
-
BOOLmerge(CStringoutfile);
-
voidInitFromStringArray(CString*pStr,intcount);
-
voidLoadFromIni(CStringstrPath);
-
voidSaveToIni(CStringstrPath);
-
intGetImageCount();
-
ImageItemimages[128];
-
private:
-
voidMyBitBlt(intindex);
-
voidDeleteRectItem(intindex);
-
voidInsertRectItem(RectItem*item);
-
voidclean();
-
RectItemrects[256];
-
intmerge_image_width;
-
intmerge_image_height;
-
intm_imageCount;
-
intm_rectCount;
- };
-
externImageListGlobalImageList;
cpp文件如下:
- ImageList::ImageList()
- {
-
memset(images,0,sizeof(images));
-
memset(rects,0,sizeof(rects));
- m_imageCount=0;
- m_rectCount=0;
- merge_image_width=0;
- merge_image_height=0;
- }
- ImageList::~ImageList()
- {
- clean();
- }
-
intImageList::GetImageCount()
- {
-
returnm_imageCount;
- }
-
voidImageList::Insert(CStringstrPath)
- {
- ImageItemitem;
-
item.hbmp=(HBITMAP)LoadImage(AfxGetInstanceHandle(),
-
(LPCTSTR)strPath,
- IMAGE_BITMAP,
- 0,
- 0,
- LR_LOADFROMFILE);
-
if(item.hbmp==NULL)
- {
- CStringstr;
-
str.Format("无法打开指定的图片:%s",strPath);
- AfxMessageBox(str);
-
}else
- {
-
GetObject(item.hbmp,sizeof(BITMAP),&item.bmp);
- }
-
- strcpy(item.filename,strPath.GetBuffer(strPath.GetLength()));
-
-
for(inti=0;i<m_imageCount;i++)
- {
-
if(item.bmp.bmWidth>images[i].bmp.bmWidth)
-
break;
-
if(item.bmp.bmWidth==images[i].bmp.bmWidth&&item.bmp.bmHeight>images[i].bmp.bmHeight)
-
break;
- }
-
for(intj=m_imageCount;j>i;j--)
- {
-
memcpy(&images[j],&images[j-1],sizeof(ImageItem));
- }
-
memcpy(&images[i],&item,sizeof(ImageItem));
- m_imageCount++;
-
-
for(i=0;i<m_imageCount;i++)
- {
- images[i].id=i+1;
- }
- }
-
BOOLImageList::merge(CStringoutfile)
- {
- merge_image_width=GetMaxWidth();
-
for(inti=0;i<m_imageCount;i++)
- {
- MyBitBlt(i);
- }
-
unsignedintwidth=merge_image_width;
-
unsignedintheight=merge_image_height;
-
HDCimgDC=CreateCompatibleDC(NULL);
-
VOID*pbits32;
-
HBITMAPholdBmp,hbm32;
- BITMAPFILEHEADERhdr;
- BITMAPINFOHEADERbmi;
-
unsignedchar*buffer;
-
HANDLEhFile;
-
intLineDataBytes=width*4;
-
intZero=(4-((width*3)%4))%4;
-
intTotalDataBytes=(width*3+Zero)*height;
-
BOOLresult=FALSE;
-
if(width<=0||height<=0)
-
returnFALSE;
-
hdr.bfType=((WORD)('M'<<8)|'B');
- hdr.bfReserved1=0;
- hdr.bfReserved2=0;
-
hdr.bfOffBits=(DWORD)(sizeof(hdr)+sizeof(bmi));
- hdr.bfSize=(width*3+Zero)*height+hdr.bfOffBits;
-
bmi.biSize=sizeof(BITMAPINFOHEADER);
- bmi.biWidth=width;
- bmi.biHeight=height;
- bmi.biPlanes=1;
- bmi.biBitCount=24;
- bmi.biCompression=BI_RGB;
- bmi.biSizeImage=0;
- bmi.biXPelsPerMeter=0;
- bmi.biYPelsPerMeter=0;
- bmi.biClrUsed=0;
- bmi.biClrImportant=0;
- hFile=CreateFile(outfile,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
-
if(INVALID_HANDLE_VALUE!=hFile)
- {
-
DWORDbw;
-
WriteFile(hFile,(LPSTR)&hdr,sizeof(hdr),&bw,NULL);
-
WriteFile(hFile,(LPSTR)&bmi,sizeof(bmi),&bw,NULL);
- bmi.biBitCount=32;
-
if(hbm32=CreateDIBSection(imgDC,(BITMAPINFO*)&bmi,DIB_RGB_COLORS,&pbits32,NULL,0))
- {
-
BYTE*p32=(BYTE*)pbits32;
-
LONG*p;
-
unsignedinti,j,h=0;
-
buffer=(unsignedchar*)malloc(TotalDataBytes);
-
holdBmp=(HBITMAP)SelectObject(imgDC,hbm32);
-
-
for(i=0;i<m_imageCount;i++)
- {
-
HDChdc=CreateCompatibleDC(NULL);
-
HBITMAPhOldBmp=(HBITMAP)SelectObject(hdc,images[i].hbmp);
- BitBlt(imgDC,images[i].x,images[i].y,images[i].bmp.bmWidth,images[i].bmp.bmHeight,hdc,0,0,SRCCOPY);
-
- DeleteDC(hdc);
- }
-
for(i=0;i<height;i++)
- {
-
for(j=0;j<width;j++)
- {
-
p=(LONG*)p32+j;
- buffer[h]=GetRValue(*p);
- buffer[h+1]=GetGValue(*p);
- buffer[h+2]=GetBValue(*p);
- h+=3;
- }
-
if(Zero)h+=Zero;
- p32+=LineDataBytes;
- }
-
WriteFile(hFile,(LPSTR)buffer,TotalDataBytes,&bw,NULL);
- DeleteObject(SelectObject(imgDC,holdBmp));
- free(buffer);
- result=TRUE;
- }
- CloseHandle(hFile);
- }
- DeleteDC(imgDC);
-
returnresult;
- }
-
voidImageList::clean()
- {
-
for(inti=0;i<m_imageCount;i++)
- {
- DeleteObject(images[i].hbmp);
- images[i].hbmp=NULL;
- }
-
memset(images,0,sizeof(images));
-
memset(rects,0,sizeof(rects));
- m_imageCount=0;
- m_rectCount=0;
- merge_image_width=0;
- merge_image_height=0;
- }
-
intImageList::GetMaxHeight()
- {
-
intheight=0;
-
for(inti=0;i<m_imageCount;i++)
- {
-
if(height<images[i].bmp.bmHeight)
- {
- height=images[i].bmp.bmHeight;
- }
- }
-
returnheight;
- }
-
intImageList::GetMaxWidth()
- {
-
intwidth=0;
-
for(inti=0;i<m_imageCount;i++)
- {
-
if(width<images[i].bmp.bmWidth)
- {
- width=images[i].bmp.bmWidth;
- }
- }
-
returnwidth;
- }
-
voidImageList::SaveToIni(CStringstrPath)
- {
-
CStringsessionName="Bitmap";
-
charkey[64];
-
charvalue[1024];
-
memset(value,0,sizeof(value));
-
sprintf(value,"%i",m_imageCount);
-
WritePrivateProfileString(sessionName,"count",value,strPath);
-
for(inti=0;i<m_imageCount;i++)
- {
-
memset(key,0,sizeof(key));
-
sprintf(key,"bmp%d",i);
-
memset(value,0,sizeof(value));
- WritePrivateProfileString(sessionName,key,images[i].filename,strPath);
- }
- }
-
voidImageList::LoadFromIni(CStringstrPath)
- {
-
CStringsessionName="Bitmap";
-
charkey[64];
-
charvalue[1024];
- CStringfilePath[100];
-
intfileCount=0;
-
-
memset(value,0,sizeof(value));
-
GetPrivateProfileString(sessionName,"count","",value,sizeof(value),strPath);
-
sscanf(value,"%i",&fileCount);
-
-
for(inti=0;i<fileCount;i++)
- {
-
memset(key,0,sizeof(key));
-
sprintf(key,"bmp%d",i);
-
memset(value,0,sizeof(value));
-
GetPrivateProfileString(sessionName,key,"",value,sizeof(value),strPath);
- filePath[i].Format(value);
- }
-
- InitFromStringArray(filePath,fileCount);
- }
-
voidImageList::InitFromStringArray(CString*pStr,intcount)
- {
- clean();
-
for(inti=0;i<count;i++,pStr++)
- {
- Insert(*pStr);
- }
- }
-
voidImageList::MyBitBlt(intimage_index)
- {
-
inti;
- searchproper:
-
for(i=0;i<m_rectCount;i++)
- {
-
-
if(images[image_index].bmp.bmWidth==rects[i].width&&
- images[image_index].bmp.bmHeight==rects[i].height)
- {
- images[image_index].x=rects[i].x;
- images[image_index].y=rects[i].y;
- DeleteRectItem(i);
-
return;
- }
-
-
if(images[image_index].bmp.bmWidth==rects[i].width&&
- images[image_index].bmp.bmHeight<rects[i].height)
- {
- images[image_index].x=rects[i].x;
- images[image_index].y=rects[i].y;
-
- RectItemtemp;
- temp.height=rects[i].height-images[image_index].bmp.bmHeight;
- temp.width=rects[i].width;
- temp.x=rects[i].x;
- temp.y=rects[i].y+images[image_index].bmp.bmHeight;
- DeleteRectItem(i);
- InsertRectItem(&temp);
-
return;
- }
-
-
if(images[image_index].bmp.bmWidth<rects[i].width&&
- images[image_index].bmp.bmHeight==rects[i].height)
- {
- images[image_index].x=rects[i].x;
- images[image_index].y=rects[i].y;
- RectItemtemp;
- temp.height=rects[i].height;
- temp.width=rects[i].width-images[image_index].bmp.bmWidth;
- temp.x=rects[i].x+images[image_index].bmp.bmWidth;
- temp.y=rects[i].y;
- DeleteRectItem(i);
- InsertRectItem(&temp);
-
return;
- }
-
-
if(images[image_index].bmp.bmWidth<rects[i].width&&
- images[image_index].bmp.bmHeight<rects[i].height)
- {
- images[image_index].x=rects[i].x;
- images[image_index].y=rects[i].y;
- RectItemtemp1;
- temp1.height=images[image_index].bmp.bmHeight;
- temp1.width=rects[i].width-images[image_index].bmp.bmWidth;
- temp1.x=rects[i].x+images[image_index].bmp.bmWidth;
- temp1.y=rects[i].y;
- RectItemtemp2;
- temp2.height=rects[i].height-images[image_index].bmp.bmHeight;
- temp2.width=rects[i].width;
- temp2.x=rects[i].x;
- temp2.y=rects[i].y+images[image_index].bmp.bmHeight;
- DeleteRectItem(i);
- InsertRectItem(&temp1);
- InsertRectItem(&temp2);
-
return;
- }
- }
-
- RectItemnew_item;
- new_item.height=images[image_index].bmp.bmHeight;
- new_item.width=merge_image_width;
- new_item.x=0;
- new_item.y=merge_image_height;
- merge_image_height+=new_item.height;
- InsertRectItem(&new_item);
-
gotosearchproper;
- }
-
voidImageList::DeleteRectItem(intindex)
- {
-
for(inti=index;i<m_rectCount;i++)
- {
-
memcpy(&rects[i],&rects[i+1],sizeof(RectItem));
- }
- m_rectCount--;
- }
-
voidImageList::InsertRectItem(RectItem*item)
- {
-
inti,j;
-
-
for(i=0;i<m_rectCount;i++)
- {
-
if(item->width<rects[i].width)
- {
-
break;
- }
-
if(item->width==rects[i].width&&
- item->height<rects[i].height)
- {
-
break;
- }
- }
-
-
for(j=m_rectCount-1;j>=i;j--)
- {
-
memcpy(&rects[j+1],&rects[j],sizeof(RectItem));
- }
-
memcpy(&rects[i],item,sizeof(RectItem));
- m_rectCount++;
- }
测试代码如下:
- CFileDialogfileDlg(TRUE,
- NULL,
- NULL,
- OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT,
-
"bmp文件(*.bmp)|*.bmp||",
- NULL);
-
fileDlg.m_ofn.lpstrFile=newTCHAR[MAX_PATH*100];
- fileDlg.m_ofn.nMaxFile=100*MAX_PATH;
-
ZeroMemory(fileDlg.m_ofn.lpstrFile,sizeof(TCHAR)*fileDlg.m_ofn.nMaxFile);
-
if(fileDlg.DoModal()!=IDOK)return;
-
- CStringfilePath[100];
-
- POSITIONpos=fileDlg.GetStartPosition();
-
intfileCount;
-
for(fileCount=0;pos!=0;fileCount++)
- {
- CStringfile=fileDlg.GetNextPathName(pos);
-
if(file.Find(".bmp")==-1)
- {
-
AfxMessageBox("非bmp文件,程序退出。");
- exit(1);
- }
- filePath[fileCount]=file;
- }
- GlobalImageList.InitFromStringArray(filePath,fileCount);
-
GlobalImageList.merge("merge.bmp");
以下是合并图片的测试效果:
合并的每一张小图片是从一张合照里剪切下来的,每张小图片的大小是不一样的,而且是未知的。从效果可以看得出,该算法尽可能地将图片挤在一起,但也还有待改进之处。
分享到:
相关推荐
批量快速将多张bmp图片转换为bin文件,bmp图片位深度为24bit,bin文件可选择8bit(RGB323)、16bit(RGB565)、24bit(RGB888) 输出,用于烧录到 外部flash,单片机去读取数据显示图像。因为输出每张bmp图片所在flash里的...
这是一款将图像文件(包括TIFF、JPG、JP2/J2K/JPC、PNG、GIF、BMP)合并、转换成PDF文件的软件。FAQ Q:FreePic2Pdf是什么?A:这是一个将图像文件(包括TIFF、JPG、JP2/J2K/JPC、PNG、GIF、BMP、webp)合并、转换成...
将图像文件(包括TIFF、JPG、PNG、GIF、BMP)合并、转换成PDF文件的软件: 对有损压缩的JPG文件及采用JPEG/OJPEG算法压缩的TIFF文件,直接将原始数据流嵌入PDF文件,避免因为重新压缩而造成图像质量下降;对无损压缩...
基于小波零树的图像压缩算法 利用OpenGL实现动画效果 逆滤波处理 实现图案化和抖动技术以及bmp2txt源代码 屏幕保护程序与源代码 屏幕颜色拾取器源代码 曲线处理 贝塞尔曲线程序 实现图象平滑(去噪声) 锐化算法的源...
软件采用高级优秀算法,在对原有图片数据最大程度保真的同时,具有特别快速的处理速度; 软件体积小巧,是一款绿色软件,免安装; 操作简单: 回车键,开始/暂停操作; ESC键 ,停止操作。
本书主要论述了智能图像处理技术,系统介绍了智能图像处理技术的有代表性的思想、算法与应用,跟踪了图像处理技术的发展前沿。全书共分为15章,重点讨论了图像边缘检测、图像分割、图像特征分析、图像配准、图像融合...
1、能对图像文件(bmp、 jpg、 tiff、 gif等)进行打开、保存、另存、打印、退出等功能操作; 2、数字图像的统计信息功能:包括直方图的统计及绘制、区域图的面积、周长的统计、线条图中的距离测量等; 3、数字图像...
将图像文件(包括TIFF、JPG、PNG、GIF、BMP)合并、转换成PDF文件的软件: 对有损压缩的JPG文件及采用JPEG/OJPEG算法压缩的TIFF文件,直接将原始数据流嵌入PDF文件,避免因为重新压缩而造成图像质量下降;对无损压缩...
1、 能对图像文件(bmp、 jpg、 tiff、 gif等)进行打开、保存、另存、打印、退出等功能操作; 2、 数字图像的统计信息功能:包括直方图的统计及绘制、区域图的面积、周长的统计、线条图中的距离测量等; 3、 数字...
1、 能对图像文件(bmp、 jpg、 tiff、 gif等)进行打开、保存、另存、打印、退出等功能操作; 2、 数字图像的统计信息功能:包括直方图的统计及绘制、区域图的面积、周长的统计、线条图中的距离测量等; 3、 数字...
PNG、JPEG 或 BMP 图像,只需选择包含图像参数的着色算法,大家就可以选择计算机上的任何图像来使用,Ultra Fractal分形艺术软件还允许用户通过使用图层、蒙版、图层组功能到到类似PS那样的合并模式来合成分形综合...
PNG、JPEG 或 BMP 图像,只需选择包含图像参数的着色算法,大家就可以选择计算机上的任何图像来使用,Ultra Fractal分形艺术软件还允许用户通过使用图层、蒙版、图层组功能到到类似PS那样的合并模式来合成分形综合...
这是一个将图像文件(包括TIFF、JPG、JP2/J2K/JPC、PNG、GIF、BMP)合并、转换成PDF文件的软件。 也可以修复pdf书签乱码问题(一般是编码问题) 方法:启动软件,在右下角点击“更改pdf”,点击“从pdf取书签”选择...
这是一个将图像文件(包括TIFF、JPG、JP2/J2K/JPC、PNG、GIF、BMP)合并、转换成PDF文件的软件。 FreePic2Pdf纯免费,并具有下列特色: 1. 对有损/无损压缩jpeg 2000(jp2/j2k/jpc)文件,或有损压缩JPG文件及...
第六章 1、Win9x/ME系统下的磁盘扇区...1、基于24位bmp位图的信息隐藏编程实例 2、基于一阶Bézier曲线的信息隐藏编程实例 第十章 1、文件分割与合并实例——单线程模式 2、文件分割与合并实例——多线程模式
这是一个将图像文件(包括TIFF、JPG、JP2/J2K/JPC、PNG、GIF、BMP)合并、转换成PDF文件的软件。纯免费,并具有下列特色: <br>对有损/无损压缩jpeg 2000(jp2/j2k/jpc)文件,或有损压缩JPG文件及采用JPEG/OJPEG...
算法思想: (1)对8、16、24位位图数据的读功能 有一个参数为输入位图文件名(*.bmp),它能解析8、16、24位位图文件格式,获取位图BITMAPINFOHEADER信息和每个像素的数据信息,放入内存中。 (2)对8、16、24位...
6.图片的合并与切割;7.读取粘贴板上的图片;8.指定大小尺寸保存图片; 属性功能:1.几何属性,颜色,线型,线宽;2.图层属性:显示,隐藏,冻结;3.尺寸属性:颜色,箭头,尺寸线属性,尺寸引线属性,...