c#利用内存拷贝方式改变bitmap图像宽高(C# using memory copy method to change the width and height of bitmap image)

c#内存拷贝有Marshal.Copy方法,适合托管内存和非托管内存之间的拷贝。然而图像之间的内存拷贝都位于非托管内存,想用Marshal类需要先从非托管内存复制到托管内存,最后再复制到非托管内存,效率减半。最后借助win32自带的CopyMemory方法成功实现。

        [DllImport("kernel32.dll", EntryPoint = "CopyMemory")]
        public extern static void CopyMemory(IntPtr dst, IntPtr src, int length);

        /// <summary>
        /// 改变图像宽高
        /// </summary>
        public static Bitmap ReSize(Bitmap src, int w, int h)
        {
            if (src == null || w < 1 || h < 1) return null;//或者抛出异常
            var srcData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, src.PixelFormat);
            var dst = new Bitmap(w, h, src.PixelFormat);
            var dstData = dst.LockBits(new Rectangle(0, 0, dst.Width, dst.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, dst.PixelFormat);
            var pSrc = srcData.Scan0;
            var pDst = dstData.Scan0;
            int wLen = w > src.Width ? srcData.Stride : dstData.Stride;//要拷贝的图像字节宽度
            int hLen = h > src.Height ? src.Height : h;//要拷贝的图像高度
            for (int i = 0; i <hLen; i++)
            {
                CopyMemory(pDst, pSrc, wLen);
                pSrc += srcData.Stride;
                pDst += dstData.Stride;
            }
            src.UnlockBits(srcData);
            dst.UnlockBits(dstData);
            return dst;
        }
————————

C# memory copy has marshal. Copy method, which is suitable for copying between managed memory and unmanaged memory. However, the memory copies between images are located in unmanaged memory. If you want to use Marshal class, you need to copy from unmanaged memory to managed memory, and then to unmanaged memory. The efficiency is halved. Finally, it is successfully implemented with the CopyMemory method of Win32.

        [DllImport("kernel32.dll", EntryPoint = "CopyMemory")]
        public extern static void CopyMemory(IntPtr dst, IntPtr src, int length);

        /// <summary>
        /// 改变图像宽高
        /// </summary>
        public static Bitmap ReSize(Bitmap src, int w, int h)
        {
            if (src == null || w < 1 || h < 1) return null;//或者抛出异常
            var srcData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, src.PixelFormat);
            var dst = new Bitmap(w, h, src.PixelFormat);
            var dstData = dst.LockBits(new Rectangle(0, 0, dst.Width, dst.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, dst.PixelFormat);
            var pSrc = srcData.Scan0;
            var pDst = dstData.Scan0;
            int wLen = w > src.Width ? srcData.Stride : dstData.Stride;//要拷贝的图像字节宽度
            int hLen = h > src.Height ? src.Height : h;//要拷贝的图像高度
            for (int i = 0; i <hLen; i++)
            {
                CopyMemory(pDst, pSrc, wLen);
                pSrc += srcData.Stride;
                pDst += dstData.Stride;
            }
            src.UnlockBits(srcData);
            dst.UnlockBits(dstData);
            return dst;
        }