iOS Code Snippet GetPixelColor

Discussion in 'iOS Code Snippets' started by JanPRO, Aug 4, 2015.

  1. JanPRO

    JanPRO Well-Known Member Licensed User

    Based on http://stackoverflow.com/questions/3284185/get-pixel-color-of-uiimage

    Code:
    Sub GetPixelColor(Bitm As Bitmap, x As Int, y As Int) As Int
         
    Dim NativeMe As NativeObject = Me
         
    Dim UIColor As Object = NativeMe.RunMethod("GetPixelColor:::"Array (Bitm,x,y))
         
    return NativeMe.UIColorToColor(UIColor)
    End Sub


    #If OBJC

    - (UIColor *)GetPixelColor:(UIImage *)bitmap :(int)x :(int)y {
      
        CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(bitmap.CGImage));
        const UInt8* data = CFDataGetBytePtr(pixelData);
      
        int pixelInfo = ((bitmap.size.width  * y) + x ) * 4;

        UInt8 red = data[pixelInfo];
        UInt8 green = data[(pixelInfo + 1)];
        UInt8 blue = data[pixelInfo + 2];
        UInt8 alpha = data[pixelInfo + 3];
        CFRelease(pixelData);

        return [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];
    }
    #End If
     
    Pooya1, cloner7801, joilts and 6 others like this.
  2. joop

    joop Active Member Licensed User

    Hi Jan, is het also possible to do the other way around in objective c?
    Setting the pixel-color in a bitmap , with the four values something like SetPixelColor(bitm,r,g,b,a)

    I am not an expert on objective c.o_O
     
  3. JanPRO

    JanPRO Well-Known Member Licensed User

    Hi,
    you can use also a canvas:
    Code:
    Sub SetPixelColor(aBitmap As Bitmap,X As Int,Y As Int, Color As Int) As Bitmap
       
    Dim Scale As Float = GetDeviceLayoutValues.NonnormalizedScale
       
    Dim img As ImageView
       img.Initialize(
    "")
       img.Width = aBitmap.Width / Scale
       img.Height = aBitmap.Height/ Scale
       img.Bitmap = aBitmap
      
       
    Dim cvs As Canvas
       cvs.Initialize(img)
      
       
    Dim PointRect As Rect
       PointRect.Initialize(X/Scale,Y/Scale,(X+
    1)/Scale,(Y+1)/Scale)
      
       cvs.DrawRect(PointRect,Color,
    True,1/Scale)
       
    Dim res As Bitmap = cvs.CreateBitmap
       cvs.Refresh
       
    Return res
    End Sub
     
  4. joop

    joop Active Member Licensed User

    Thanks Jan I will try it.
     
  5. JordiCP

    JordiCP Well-Known Member Licensed User

    I'm aware that this is an old post, but as it is a useful Code Snippet, I think it needs a small correction otherwise it won't always work (unless I'm totally wrong, since I'm still learning) and give some headaches.

    After some hours experiencing strange results, I noticed that it only worked for me if I extracted pixels from the first bitmap row.
    So, investigating a bit I found that bitmaps can have a similar memory organisation as in Android, i.e., there can be a padding at the end of each row depending on bitmap width. The correct code (I believe) is:
    Code:
    #If OBJC

    - (UIColor *)GetPixelColor:(UIImage *)bitmap :(int)x :(int)y {
     
        CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(bitmap.CGImage));
        const UInt8* data = CFDataGetBytePtr(pixelData);
     
        //int pixelInfo = ((bitmap.size.width  * y) + x ) * 4;   //<-- Not always true!!
        
        // Add these 2 lines instead
        int stride = CGImageGetBytesPerRow(bitmap.CGImage); 
        int pixelInfo = (stride  * y) + x*4 ;

        UInt8 red = data[pixelInfo];
        UInt8 green = data[(pixelInfo + 1)];
        UInt8 blue = data[pixelInfo + 2];
        UInt8 alpha = data[pixelInfo + 3];
        CFRelease(pixelData);

        return [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];
    }
    #End If
     
    Pooya1, JanPRO and Erel like this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice