代码之家  ›  专栏  ›  技术社区  ›  Larry OBrien

检索uiimage的像素alpha值(monotouch)

  •  2
  • Larry OBrien  · 技术社区  · 15 年前

    这个问题是 1042830 ,但单点触控。有没有比分配intptr更安全的方法,使用cgbitmapcontext绘制intptr,然后在适当的偏移量读取字节?

    1 回复  |  直到 15 年前
        1
  •  5
  •   Larry OBrien    15 年前

    我不知道回答你自己的问题是否是清正廉洁的,但是:

        protected CGBitmapContext CreateARGBBitmapContext(CGImage inImage)
        {
            var pixelsWide = inImage.Width;
            var pixelsHigh = inImage.Height;
            var bitmapBytesPerRow = pixelsWide * 4;
            var bitmapByteCount = bitmapBytesPerRow * pixelsHigh;
            //Note implicit colorSpace.Dispose() 
            using(var colorSpace = CGColorSpace.CreateDeviceRGB())
            {
                //Allocate the bitmap and create context
                var bitmapData = Marshal.AllocHGlobal(bitmapByteCount);
                //I think this is unnecessary, as I believe Marshal.AllocHGlobal will throw OutOfMemoryException
                if(bitmapData == IntPtr.Zero)
                {
                    throw new Exception("Memory not allocated.");
                }
    
                var context = new CGBitmapContext(bitmapData, pixelsWide, pixelsHigh, 8,
                                                  bitmapBytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedFirst);
                if(context == null)
                {
                    throw new Exception("Context not created");
                }
                return context;
            }
        }
    
        //Store pixel data as an ARGB Bitmap
        protected IntPtr RequestImagePixelData(UIImage inImage)
        {
            imageSize = inImage.Size;
            CGBitmapContext ctxt = CreateARGBBitmapContext(inImage.CGImage);
            var rect = new RectangleF(0.0f, 0.0f, imageSize.Width, imageSize.Height);
            ctxt.DrawImage(rect, inImage.CGImage);
            var data = ctxt.Data;
            return data;
        }
    
        //Note: Unsafe code
        unsafe byte GetByte(int offset, IntPtr buffer)
        {
            byte* bufferAsBytes = (byte*) buffer;
            return bufferAsBytes[offset];
        }
    
        //Example of using it...
        public override bool PointInside (PointF point, UIEvent uievent)
        {
             //Lazy initialize
            if(bitmapData == IntPtr.Zero)
            {
                bitmapData = RequestImagePixelData(Image);
            }
    
            //Check for out of bounds
            if(point.Y < 0 || point.X < 0 || point.Y > Image.Size.Height || point.X > Image.Size.Width)
            {
                return false;
            }
            var startByte = (int) ((point.Y * this.Image.Size.Width + point.X) * 4);
    
            byte alpha = GetByte(startByte, this.bitmapData);
            Console.WriteLine("Alpha value of {0}, {1} is {2}", point.X, point.Y, alpha);
                        ...etc...