1

Is it possible to programmatically measure the padding (clear space) on the sides (left right top bottom) of a PNG in C#? Could I somehow parse the image pixel by pixel starting at the sides checking to see if the pixel has any thing in it that's not clear or empty? How would I determine that the pixel is empty as opposed to a color?

My PNG is loaded onto a UIImageView, but I could process either the PNG or the UIImage/UIImageView. What ever works.

Here's a PNG

Here's a PNG

Here's what I want to measure

Here's what I want to measure programmatically.

-------------- Solution posted here ----------------

    UIImage Image = UIImage.FromFile("image.png");
    IntPtr bitmapData = RequestImagePixelData(Image);


    PointF point = new PointF(100,100);

    //Check for out of bounds
    if(point.Y < 0 || point.X < 0 || point.Y > Image.Size.Height || point.X > Image.Size.Width)
    {
        Console.WriteLine("out of bounds!");
    }
    else
    {
        Console.WriteLine("in bounds!");


        var startByte = (int) ((point.Y * Image.Size.Width + point.X) * 4);

        byte alpha = GetByte(startByte, bitmapData);

        Console.WriteLine("Alpha value of an image of size {0} at point {1}, {2} is {3}", Image.Size, point.X, point.Y, alpha);
    }




    protected IntPtr RequestImagePixelData(UIImage InImage)
    {
        CGImage image = InImage.CGImage;
        int width = image.Width;
        int height = image.Height;
        CGColorSpace colorSpace = image.ColorSpace;
        int bytesPerRow = image.BytesPerRow;
        int bitsPerComponent = image.BitsPerComponent;
        CGImageAlphaInfo alphaInfo = image.AlphaInfo;

        IntPtr rawData;

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

        return context.Data;
    }


    //Note: Unsafe code.  Make sure to allow unsafe code in your
    unsafe byte GetByte(int offset, IntPtr buffer)
    {
        byte* bufferAsBytes = (byte*) buffer;
        return bufferAsBytes[offset];
    }

Obviously now I need to make the logic that parses each pixel and determines where the clear pixels stop. That logic is very simple so I won't bother posting that. Simply start from the sides and work your way in until you find an alpha value that's not zero.

Thanks to everyone for their help!

LampShade
  • 2,675
  • 5
  • 30
  • 60
  • Please be more specific. Do you want to process png file, or an image loaded into your app? Had you tried anything? – David Goshadze Feb 19 '13 at 14:55
  • I was thinking of processing the PNG file. If there is a way to process the UIImage I could do it that way too, but I don't know of a way to do either at the moment – LampShade Feb 19 '13 at 14:56

1 Answers1

1

You could check if the pixel is empty by checking if its Alpha value is equal to (or close to) 0. Not sure of which API you are using, but you should be able to get the pixel's color in RGBA.

Scanning in lines should allow you to determine how much of the border is 'empty'.

Mike the Tike
  • 1,136
  • 8
  • 9
  • Do you know how to parse the UIImage or the PNG itself? If my UIImage variable is named "myImage", I can see some useful information like myImage.CGImage.BytesPerRow and myImage.CGImage.Height, myImage.CGImage.Width. But how do I parse the image? – LampShade Feb 19 '13 at 15:32
  • 1
    I haven't got monotouch installed, so I can't give you an exact answer, but it looks similar to this question:http://stackoverflow.com/questions/2597198/retrieving-a-pixel-alpha-value-for-a-uiimage-monotouch – Mike the Tike Feb 19 '13 at 15:44
  • Thanks a bunch! I was looking at this but had some issues implementing it because the code syntax has changed since that post. I've posed my working source code for anyone who's interested. – LampShade Feb 19 '13 at 16:23