2012-12-14 97 views
4

我已经创建了一个方法,我要拍摄图像蒙版并将其应用于其他图像。如果你看看这个post,你会看到一个帧图像。该文章中的帧图像是maskingImage,背景图像是imageToMask。蒙版图像真的是一个粉红色中心的图像。这是该方法经历的过程:Bitmap.LockBits错误“参数无效”当位图是一定大小?

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

回答

5

原因是你正在使用的矩形图像大于位图本身。

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

rect用于指定需要锁定的位图区域。该矩形可以与位图大小相同或更小,但不能更大。 在你的情况下,因为你使用基于你的maskingImage的矩形,矩形变得比你使用它的位图更大,从而导致你的错误。

+0

确切地说,有什么解决方案来解决这个问题? – DDiVita

+0

一个解决方案会为每个位图(maskImage,imageToMask和输出)创建一个单独的矩形。例如,我会首先检查maskImage的宽度和高度是否小于imageToMask的宽度和高度。如果是,则使用输出的maskingImage的宽度,如果不是,则使用输出图像的imageToMask的宽度/高度,并根据3个位图创建3个矩形。 – Rutix