cropping an area from BitmapData with C#

后端 未结 5 1376
囚心锁ツ
囚心锁ツ 2020-12-17 23:28

I have a bitmap sourceImage.bmp

locking it\'s bits:

BitmapData dataOriginal = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.W         


        
5条回答
  •  臣服心动
    2020-12-17 23:50

    I am a new user and can't vote yet, otherwise I would have upvoted Korwin80's answer as it provides the most efficient working solution, in my opinion. trakos' solution may execute faster but yields scrambled images, at least for me. Here is how I applied Korwin80's solution, with some minor improvements, in my own code:

    [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
    private unsafe static extern int memcpy(byte* dest, byte* src, long count);
    
    private unsafe Bitmap Crop(Bitmap srcImg, Rectangle rectangle)
    {
        if ((srcImg.Width == rectangle.Width) && (srcImg.Height == rectangle.Height))
            return srcImg;
    
        var srcImgBitmapData = srcImg.LockBits(new Rectangle(0, 0, srcImg.Width, srcImg.Height), ImageLockMode.ReadOnly, srcImg.PixelFormat);
        var bpp = srcImgBitmapData.Stride / srcImgBitmapData.Width; // 3 or 4
        var srcPtr = (byte*)srcImgBitmapData.Scan0.ToPointer() + rectangle.Y * srcImgBitmapData.Stride + rectangle.X * bpp;
        var srcStride = srcImgBitmapData.Stride;
    
        var dstImg = new Bitmap(rectangle.Width, rectangle.Height, srcImg.PixelFormat);
        var dstImgBitmapData = dstImg.LockBits(new Rectangle(0, 0, dstImg.Width, dstImg.Height), ImageLockMode.WriteOnly, dstImg.PixelFormat);
        var dstPtr = (byte*)dstImgBitmapData.Scan0.ToPointer();
        var dstStride = dstImgBitmapData.Stride;
    
        for (int y = 0; y < rectangle.Height; y++)
        {
            memcpy(dstPtr, srcPtr, dstStride);
            srcPtr += srcStride;
            dstPtr += dstStride;
        }
    
        srcImg.UnlockBits(srcImgBitmapData);
        dstImg.UnlockBits(dstImgBitmapData);
        return dstImg;
    }
    

提交回复
热议问题