假设我有2张图片,一张在另一张图片之上。我想将顶部图像的像素的alpha值的一部分设置为零,所以我得到如下所示的效果:
棕色是顶部图像,蓝色水是底部图像。最终我要做的是让顶部图像像素的alpha通道随着用户触摸iPad屏幕而变为零,这样他们就可以用指尖绘制并显示蓝色水像。
我有一个函数可以检查图像计算其alpha等于零的像素。我还有一个函数,将像素的alpha设置为零,但我认为它不起作用。 我可以读取alpha值,并设置alpha值。然后我可以重新读取alpha值以确认它已设置。但是当我设置新图像时,我看不出有什么区别!
以下是我示例项目的保管箱链接:
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;
}
答案 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);