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

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)效果

PlayerMagic

0_0_00_0_10_0_20_0_30_0_40_0_50_0_60_0_70_0_80_0_9

posted @ 2012-02-04 23:17  杨某某  阅读(20414)  评论(3编辑  收藏  举报