【问题标题】:Retrieving a pixel alpha value for a UIImage (MonoTouch)检索 UIImage (MonoTouch) 的像素 alpha 值
【发布时间】:2011-02-05 12:48:38
【问题描述】:

此问题与 1042830 重复,但特定于 MonoTouch。有没有比分配一个 IntPtr 更安全的方法,使用 CGBitmapContext 绘制它,然后在适当的偏移量处读取字节?

【问题讨论】:

    标签: uikit uiimage xamarin.ios pixel unsafe


    【解决方案1】:

    我不知道回答你自己的问题是否合乎情理,但是:

        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...
    

    【讨论】:

      猜你喜欢
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 2013-03-19
      • 2017-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-16
      相关资源
      最近更新 更多