2013-03-19 132 views
1

比方说,我有两个图像,一个在另一个之上。我想顶端图像的像素的α值的一部分设置为零,因此我得到这种效果如下所示:设置一些像素的alpha为零

棕色是顶部图像,以及蓝色水是底部图像。最终,我要做的是当用户触摸iPad屏幕时,顶部图像的像素的alpha通道变为零,以便他们可以用指尖进行基本绘制并显示蓝色的水图像。

我有一个函数,可以检查计数它的像素的alpha等于零的图像。我也有一个函数,将像素的alpha值设为零,但我认为它不起作用。 我可以读取alpha值,并设置alpha值。然后我可以重新读取alpha值以确认它已设置。但是当我设定新的图像时,我看不出有什么不同!

这里是一个Dropbox的链接到我的示例项目:

https://www.dropbox.com/s/e93hzxl5ru5wnss/TestAlpha.zip

而且下面是源:

 Water = new UIImageView(this.Bounds); 
     Water_OriginalImage = UIImage.FromFile("Media/Images/Backgrounds/WaterTexture.png"); 
     Water.Image = Water_OriginalImage; 
     this.AddSubview(Water); 

     Dirt = new UIImageView(this.Bounds); 
     Dirt_ModifiableImage = UIImage.FromFile("Media/Images/Backgrounds/DirtBackground.png"); 
     Dirt.Image = null; 
     this.AddSubview(Dirt); 


     CGImage image = Dirt_ModifiableImage.CGImage; 
     int width = image.Width; 
     int height = image.Height; 
     CGColorSpace colorSpace = image.ColorSpace; 
     int bytesPerRow = image.BytesPerRow; 
     int bitmapByteCount = bytesPerRow * height; 
     int bitsPerComponent = image.BitsPerComponent; 
     CGImageAlphaInfo alphaInfo = image.AlphaInfo; 

     // Allocate memory because the BitmapData is unmanaged 
     IntPtr BitmapData = Marshal.AllocHGlobal(bitmapByteCount); 

     CGBitmapContext context = new CGBitmapContext(BitmapData, width, height, bitsPerComponent, bytesPerRow, colorSpace, alphaInfo); 
     context.SetBlendMode(CGBlendMode.Copy); 
     context.DrawImage(new RectangleF(0, 0, width, height), image); 


     // Console output from this function call says "alpha count = 0" 
     CountZeroedAlphas(BitmapData, Dirt_ModifiableImage); 

     RemoveSomeAlpha(BitmapData, Dirt_ModifiableImage); 

     // Console output from this function call says "alpha count = 2000". So it seems that I have set the alpha of 2000 pixels to zero... 
     CountZeroedAlphas(BitmapData, Dirt_ModifiableImage); 


     // Set the Dirt Image equal to the context image, but I still see all top image, I dont' see any bottom image showing through. 
     Dirt.Image = UIImage.FromImage (context.ToImage()); 


     // Free memory used by the BitmapData now that we're finished 
     Marshal.FreeHGlobal(BitmapData); 




    public void CountZeroedAlphas(IntPtr bitmapData, UIImage Image) 
    { 
     int widthIndex = 0; 
     int heightIndex = 0; 
     int count = 0; 

     while (widthIndex < Image.Size.Width) 
     { 
      while (heightIndex < Image.Size.Height) 
      { 
       PointF point = new PointF(widthIndex, heightIndex); 
       var startByte = (int) ((point.Y * Image.Size.Width + point.X) * 4); 
       byte alpha = GetByte(startByte, bitmapData); 

       if (alpha == 0) 
        count++; 

       heightIndex++; 
      } 


      widthIndex++; 
     } 

     Console.WriteLine("alpha count = " + count); 

    } 


    public void RemoveSomeAlpha(IntPtr bitmapData, UIImage Image) 
    { 
     int widthIndex = 0; 
     int heightIndex = 0; 

     while (widthIndex < Image.Size.Width) 
     { 
      while (heightIndex < Image.Size.Height) 
      { 
       PointF point = new PointF(widthIndex, heightIndex); 
       var startByte = (int) ((point.Y * Image.Size.Width + point.X) * 4); 
       ZeroByte(startByte, bitmapData); 

       heightIndex++; 
      } 

      widthIndex++; 
     } 

    } 


    public unsafe byte GetByte(int offset, IntPtr buffer) 
    { 
     byte* bufferAsBytes = (byte*) buffer; 
     return bufferAsBytes[offset]; 
    } 


    public unsafe void ZeroByte(int offset, IntPtr buffer) 
    { 
     byte* bufferAsBytes = (byte*) buffer; 
     bufferAsBytes[offset] = 0; 
    } 

回答

1

得到它的工作!我不确定问题究竟是什么(假设我在意外或错误的地方访问了错误的字节),但我有工作代码。

This是非常有用的:

 // Create layers of matter on the battlefield. Example: Grass, dirt, water 
     Water = new UIImageView(UIScreen.MainScreen.Bounds); 
     Water_OriginalImage = UIImage.FromFile("WaterTexture.png"); 
     Water.Image = Water_OriginalImage; 
     this.View.AddSubview(Water); 

     Dirt = new UIImageView(UIScreen.MainScreen.Bounds); 
     Dirt_ModifiableImage = UIImage.FromFile("DirtBackground.png"); 
     Dirt.Image = null; 
     this.View.AddSubview(Dirt); 



     CGImage image = Dirt_ModifiableImage.CGImage; 
     int width = image.Width; 
     int height = image.Height; 
     CGColorSpace colorSpace = image.ColorSpace; 
     int bytesPerRow = image.BytesPerRow; 
     // int bytesPerPixel = 4; 
     int bytesPerPixel = bytesPerRow/width; 
     int bitmapByteCount = bytesPerRow * height; 
     int bitsPerComponent = image.BitsPerComponent; 
     CGImageAlphaInfo alphaInfo = image.AlphaInfo; 

     // Allocate memory because the BitmapData is unmanaged 
     IntPtr BitmapData = Marshal.AllocHGlobal(bitmapByteCount); 

     CGBitmapContext context = new CGBitmapContext(BitmapData, width, height, bitsPerComponent, bytesPerRow, colorSpace, alphaInfo); 
     context.SetBlendMode(CGBlendMode.Copy); 
     context.DrawImage(new RectangleF(0, 0, width, height), image); 

     int tempX = 0; 

     while (tempX < Dirt_ModifiableImage.Size.Width) 
     { 
      int tempY = 0; 
      while (tempY < Dirt_ModifiableImage.Size.Height) 
      { 
       int byteIndex = (bytesPerRow * tempY) + tempX * bytesPerPixel; 


       ZeroByte(byteIndex+3, BitmapData); 

       byte red = GetByte(byteIndex, BitmapData); 
       byte green = GetByte(byteIndex+1, BitmapData); 
       byte blue = GetByte(byteIndex+2, BitmapData); 
       byte alpha = GetByte(byteIndex+3, BitmapData); 


       //Console.WriteLine("red = " + red + " green = " + green + " blue = " + blue + " alpha = " + alpha); 

       tempY++; 
      } 
      tempX++; 
     } 


      NSData newImageData = NSData.FromBytes(BitmapData, (uint)(bitmapByteCount)); 
      Dirt.Image = UIImage.LoadFromData(newImageData);