Read pixel data of Image in Xamarin Forms for iOS

madziemadzie Member ✭✭
edited December 2018 in Cross Platform with Xamarin

The requirement is to read the image's pixel RGB values and return them in the below format.
I got it working for Android, but is there a working equivalent of it for iOS ?

 List<List<List<int>>> imageOutput = new List<List<List<int>>>();

        Bitmap bmpImage = BitmapFactory.DecodeFile(filePath, new BitmapFactory.Options());
        try
        {
            for (int i = 0; i < bmpImage.Height; i++)
            {
                List<List<int>> eachrow = new List<List<int>>();
                for (int j = 0; j < bmpImage.Width; j++)
                {

                    int color = bmpImage.GetPixel(j, i);
                    int A = (color >> 24) & 0xff; // or color >>> 24
                    int R = (color >> 16) & 0xff;
                    int G = (color >> 8) & 0xff;
                    int B = (color) & 0xff;

                    eachrow.Add(new List<int> { R, G, B });

                }
                imageOutput.Add(eachrow);
            }
        }

Answers

  • ColeXColeX Member, Xamarin Team Xamurai

    In iOS you can use new a NSMutableArray with UIColor stored in it .

    Convert from Objective-C to C#.

     static NSMutableArray<UIColor> getRGBAsFromImage(UIImage image , int x , int y , int count)
        {
            NSMutableArray<UIColor> result = new NSMutableArray<UIColor>();
    
            // First get the image into your data buffer
            CGImage imageRef = image.CGImage;
            nint width = imageRef.Width;
            nint height = imageRef.Height;
            CGColorSpace colorSpace = CGColorSpace.CreateDeviceRGB();
            byte[] rawData = new byte[height * width *4];
            nint bytesPerPixel = 4;
            nint bytesPerRow = bytesPerPixel * width;
            nint bitsPerComponent = 8;
            CGContext context = new CGBitmapContext(null,width,height,bitsPerComponent,bytesPerRow,colorSpace, CGBitmapFlags.ByteOrder32Big | CGBitmapFlags.PremultipliedLast);
            colorSpace.Dispose();
    
            context.DrawImage(new CGRect(0,0,width,height),imageRef);
            context.Dispose();
    
            // Now your rawData contains the image data in the RGBA8888 pixel format.
            nint byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
    
            for (int i = 0; i <count; ++i)
            {
                float alpha = rawData[byteIndex + 3];
                float red = rawData[byteIndex];
                float green = rawData[byteIndex + 1];
                float blue = rawData[byteIndex + 2];
                byteIndex += bytesPerPixel;
    
                UIColor acolor = new UIColor(red, green, blue, alpha);
                result.Add(acolor);
            }
            return result;
        }
    

    Refer https://stackoverflow.com/a/1262893/8187800

  • madziemadzie Member ✭✭

    Thanks @ColeX for the information here. But how do we get X and Y ?

  • ColeXColeX Member, Xamarin Team Xamurai

    Refer :https://stackoverflow.com/questions/448125/how-to-get-pixel-data-from-a-uiimage-cocoa-touch-or-cgimage-core-graphics/1262893#comment42316796_1262893

    Note on usage: x and y are the coordinates within the image to start getting RGBAs from and 'count' is the number of pixels from that point to get, going left to right, then row by row. Example Usage: To get RGBAs for an entire image: getRGBAsFromImage:image atX:0 andY:0 count:image.size.width*image.size.height To get RGBAs for the last row of an image: getRGBAsFromImage:image atX:0 andY:image.size.height-1 count:image.size.width

Sign In or Register to comment.