【问题标题】:Bitmap.LockBits error "Parameter is not valid" when bitmap is a certain size?当位图为一定大小时,Bitmap.LockBits 错误“参数无效”?
【发布时间】:2012-12-15 03:29:21
【问题描述】:

我创建了一个方法,我想在其中获取图像蒙版并将其应用于另一个图像。如果你看看这个post,你会看到一个帧图像。该帖子中的框架图像是maskingImage,背景图像是imageToMask。掩蔽图像实际上是具有粉红色中心的图像。这是该方法所经历的过程:

  1. 屏蔽图像是 PNG,要屏蔽的图像是 JPG。
  2. 该方法跟踪遮罩图像并在其上绘制图像以遮罩。这有助于保持外部透明度不变。
  3. 然后在遮罩图像下方绘制的输出表单,我们使亮粉色透明。

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;
}

【问题讨论】:

    标签: c# .net system.drawing


    【解决方案1】:

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

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

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

    【讨论】:

    • 没错,解决这个问题的解决方案是什么?
    • 一种解决方案是为每个位图(maskImage、imageToMask 和输出)制作一个单独的矩形。例如,我首先检查 maskImage 的宽度和高度是否小于 imageToMask 的宽度和高度。如果是,则使用 maskingImage 的宽度作为输出,如果不是,则使用 imageToMask 的宽度/高度作为输出图像,然后根据 3 个位图创建 3 个矩形。
    猜你喜欢
    • 2017-11-03
    • 2020-08-28
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    相关资源
    最近更新 更多