您的位置:首页 > 编程语言 > C#

C# WinForm 使用多种方法实现 图片的切割和拼接

2012-02-04 23:17 926 查看

1、通过拷贝像素 实现图片的切割和拼接

来自:百度空间http://hi.baidu.com/%B2%E8%B6%E0%B7%D3%BB%BC%D5%DF/blog/item/051081c7df4c5c069c163da6.html

这种方法我不想试了,效率太低了

try
{
int count = myarray.Count;//动态数据,保存所有图片的Top和Left,以及最大点的坐标 int width = (((int)myarray[count - 2])/256+1)*256;//使动态生成的图片长和宽式256的整数倍
int height = (((int)myarray[count - 1])/256+1)*256;
Bitmap newBitmap = new Bitmap(width,height);
Color pixel;
int width1 = 0, height1 = 0;
for (int j = 0; j <(count-2)/2; j++)
{
Bitmap oldBitmap=(Bitmap)((PictureBox)this.Controls.Find("newpicturebox"+j, true)[0]).Image;
width1 = ((PictureBox)this.Controls.Find("newpicturebox"+j, true)[0]).Image.Width;
height1 = ((PictureBox)this.Controls.Find("newpicturebox"+j, true)[0]).Image.Height;
int px =Convert.ToInt16(myarray[j*2]);// ((PictureBox)this.Controls.Find("newpicturebox" + j, true)[0]).Location.X;
int py=Convert.ToInt16(myarray[j*2+1]);//((PictureBox)this.Controls.Find("newpicturebox"+j, true)[0]).Location.Y;
for(int p=0;p<width1;p++)
for (int q=0; q<height1; q++)
{
pixel = oldBitmap.GetPixel(p,q);
newBitmap.SetPixel(px+p,py+q, pixel);
}
}
Clear();
this.pictureBox1.Size = new Size(width,height);
this.pictureBox1.Image = newBitmap;
newBitmap.Save(DirectoryInfoPath+"00.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "信息提示");
} 图片切割: int width2 = this.pictureBox1.Width;
int height2 = this.pictureBox1.Height;
Bitmap newBitmap = new Bitmap(256, 256);
Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
for (int i = 0; i <width2 / 256; i++)
for (int j = 0; j < height2 / 256; j++)
{
for (int p =i * 256; p < i * 256 + 256; p++)
for (int q = i * 256; q < j * 256 + 256; q++)
{
pixel = oldBitmap.GetPixel(p, q);
newBitmap.SetPixel(p%256,q%256, pixel);
}
newBitmap.Save(DirectoryInfoPath +"新"+i+j+ ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}

2、使用Graphics类中的DrawImage方法,实现图片的拼接Graphics draw;

来自:博客园http://www.cnblogs.com/youwang/archive/2011/12/22/2298594.html

private Image JoinImage(List imageList, JoinMode jm)
{
//图片列表
if (imageList.Count <= 0)
return null;
if (jm == JoinMode.Horizontal)
{
//横向拼接
int width = 0;
//计算总长度
foreach (Image i in imageList)
{
width += i.Width;
}
//高度不变
int height = imageList.Max(x => x.Height);
//构造最终的图片白板
Bitmap tableChartImage = new Bitmap(width, height);
Graphics graph = Graphics.FromImage(tableChartImage);
//初始化这个大图
graph.DrawImage(tableChartImage, width, height);
//初始化当前宽
int currentWidth = 0;
foreach (Image i in imageList)
{
//拼图
graph.DrawImage(i, currentWidth, 0);
//拼接改图后,当前宽度
currentWidth += i.Width;
}
return tableChartImage;
}
else if (jm == JoinMode.Vertical)
{
//纵向拼接
int height = 0;
//计算总长度
foreach (Image i in imageList)
{
height += i.Height;
}
//宽度不变
int width = imageList.Max(x => x.Width);
//构造最终的图片白板
Bitmap tableChartImage = new Bitmap(width, height);
Graphics graph = Graphics.FromImage(tableChartImage);
//初始化这个大图
graph.DrawImage(tableChartImage, width, height);
//初始化当前宽
int currentHeight = 0;
foreach (Image i in imageList)
{
//拼图
graph.DrawImage(i, 0, currentHeight);
//拼接改图后,当前宽度
currentHeight += i.Height;
}
return tableChartImage;
}
else
{
return null;
}
}
也做了一个很简陋的图像界面,如下图所示:



3、使用[API-BitBlt]

(1)、声明API

#region Win32API
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // 目标 DC的句柄
int nXDest,
int nYDest,
int nWidth,
int nHeight,
IntPtr hdcSrc, // 源DC的句柄
int nXSrc,
int nYSrc,
System.Int32 dwRop // 光栅的处理数值
);

[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hdc);

[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);
#endregion

(2)、函数

const int SRCCOPY = 0x00CC0020;
public bool CutPictrueToStream(Bitmap BmpSource)
{

Graphics grSource = Graphics.FromImage(BmpSource);
Bitmap Bitmap_cutted = new Bitmap(SizeX, SizeY, grSource);
IntPtr hdcTarget = IntPtr.Zero;
IntPtr hdcSource = IntPtr.Zero;
IntPtr hBitmapSource = IntPtr.Zero;
IntPtr hOldObject = IntPtr.Zero;

hBitmapSource = BmpSource.GetHbitmap();

MemorySource = new MemoryStream[ClassCount][][];
for (int i = 0; i < ClassCount; i++)
{
MemorySource[i] = new MemoryStream[DirectionCount][];
for (int j = 0; j < DirectionCount; j++)
{
MemorySource[i][j] = new MemoryStream[Frames[i]];
for (int k = 0; k < Frames[i]; k++)
{
Graphics grTarget = Graphics.FromImage(Bitmap_cutted);
hdcTarget = grTarget.GetHdc();
hdcSource = grSource.GetHdc();
hOldObject = SelectObject(hdcSource, hBitmapSource);
BitBlt(hdcTarget, 0, 0, SizeX, SizeY, hdcSource, (i * Frames[i] + k) * SizeX, j * SizeY, SRCCOPY);

//必须释放DC,否则保存为黑图
if (hdcTarget != IntPtr.Zero)
{
grTarget.ReleaseHdc(hdcTarget);
}
if (hdcSource != IntPtr.Zero)
{
grSource.ReleaseHdc(hdcSource);
}
Bitmap_cutted.MakeTransparent();//保存为透明背景
Bitmap_cutted.Save(@"F:\Project\VS 2008\C#\(十一)地图遮罩层的实现\(十一)地图遮罩层的实现\Player\" + i.ToString() + "_" + j.ToString() + "_" + k.ToString() + ".Png",ImageFormat.Png);

//                         MemorySource[i][j][k] = new MemoryStream();
//                         Bitmap_cutted.Save(MemorySource[i][j][k], ImageFormat.Png);
grTarget.Dispose();
}
}
}

if (hOldObject != IntPtr.Zero)
SelectObject(hdcSource, hOldObject);
if (hBitmapSource != IntPtr.Zero)
DeleteObject(hBitmapSource);

grSource.Dispose();
Bitmap_cutted.Dispose();

return true;
}

(3)效果

























内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐