当位图是一定大小时,Bitmap.LockBits错误“参数无效”?

时间:2012-12-14 18:42:12

标签: c# .net system.drawing

我创建了一个方法,我想拍摄一个图像蒙版并将其应用到另一个图像。如果你看一下这个post,你会看到一个帧图像。该帖子中的框架图片为maskingImage,背景图片为imageToMask。遮蔽图像实际上是一个粉红色中心的图像。这是该方法的过程:

  1. 屏蔽图像是PNG,要屏蔽的图像是JPG。
  2. 该方法跟踪掩蔽图像并绘制图像以掩盖它。这有助于保持外部透明度不变。
  3. 然后在屏蔽图像下方绘制输出表格,我们将粉红色的颜色设为透明。
  4. var bitsimageToMask = imageToMask.LockBits...是我收到错误的地方。如果要屏蔽的图像的宽度或高度小于屏蔽图像,则会出现“参数无效”错误。在使用位图时,我是新手。

    public Bitmap RenderMaskedImage(Bitmap maksingImage, Bitmap imageToMask, Point imageToMaskOffset, ImageFormat imageFormat)
    {
        using (var newImageToMaskGraphic = Graphics.FromImage(imageToMask))
        {
        newImageToMaskGraphic.DrawImage(imageToMask, imageToMaskOffset);
        }
    
        var output = new Bitmap(maksingImage.Width, maksingImage.Height, PixelFormat.Format32bppArgb);
        var rect = new Rectangle(0, 0, maksingImage.Width, maksingImage.Height);
        var bitsMask = maksingImage.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        var bitsimageToMask = imageToMask.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        var bitsOutput = output.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
    
        unsafe
        {
            for (int y = 0; y < maksingImage.Height; y++)
            {
                var ptrMask = (byte*)bitsMask.Scan0 + y * bitsMask.Stride;
                var ptrimageToMask = (byte*)bitsimageToMask.Scan0 + y * bitsimageToMask.Stride;
                var ptrOutput = (byte*)bitsOutput.Scan0 + y * bitsOutput.Stride;
                for (int x = 0; x < maksingImage.Width; x++)
                {
                    ptrOutput[4 * x] = ptrimageToMask[4 * x];           // blue
                    ptrOutput[4 * x + 1] = ptrimageToMask[4 * x + 1];   // green
                    ptrOutput[4 * x + 2] = ptrimageToMask[4 * x + 2];   // red
                    ptrOutput[4 * x + 3] = ptrMask[4 * x + 3];        // alpha 
                }
            }
        }
    
        maksingImage.UnlockBits(bitsMask);
        imageToMask.UnlockBits(bitsimageToMask);
        output.UnlockBits(bitsOutput);
    
        using (var outputGraphic = Graphics.FromImage(output))
        {
            outputGraphic.DrawImage(maksingImage.ToTransparentColor(255,0,192), 0, 0);
        }
    
        return output;
    }
    

1 个答案:

答案 0 :(得分:6)

原因是你在imageToMask上使用的矩形比位图本身大。

var rect = new Rectangle(0, 0, maksingImage.Width, maksingImage.Height);
var bitsimageToMask = imageToMask.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

rect用于指定需要锁定的位图区域。这个rec​​t可以与位图相同或更小,但不能更大。 在你的情况下,因为你使用基于maskingImage的矩形,矩形变得比你使用它的位图大,这会给你带来错误。