Flip an NSBitmapImageRep

  • I can't seem to find a way to flip an NSBitmapImageRep horizontally.  And
    yes, I *have* looked through the documentation... I am just missing it.

    Any pointers would be appreciated.

    Thanks
  • On Oct 13, 2006, at 2:49 PM, Simon Raisin wrote:

    > I can't seem to find a way to flip an NSBitmapImageRep
    > horizontally.  And
    > yes, I *have* looked through the documentation... I am just missing
    > it.

    Have you looked into CoreImage?

    If CI is not an option for you, I would recommend doing direct pixel
    access.  You can see this at work in:

    <http://developer.apple.com/samplecode/Monochrome_Image/index.html>

    Specifically, look at NSImage_monochrome.m.  You could keep it as-is
    in terms of producing a new "h-flipped" image.  You could, however,
    modify it to do a more in-place flip on the same rep.

    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • On 10/13/06, Ricky Sharp <rsharp...> wrote:
    >
    >
    > Have you looked into CoreImage?

    That you for the prompt response Ricky.  I *have* looked at CI, but again, I
    must not be looking at the right things.  I see things like filters,
    vectors, etc., but I can't seem to track down anything that performs "basic"
    tasks like rotation & flipping.

    Any specific pointers to the docs would be greatly appreciated!
  • Hi Simon-

    I tried to answer your first request, but couldn't find horizontal
    flips specifically in the core image docs.  Rotation is in there.
    Here was what I was going to suggest:

    Example of image processing in Core Image:

    file:///Developer/ADC%20Reference%20Library/documentation/
    GraphicsImaging/Conceptual/CoreImaging/ci_tasks/chapter_3_section_4.html

    List of Apple provided CIFilters:

    file:///Developer/ADC%20Reference%20Library/documentation/
    GraphicsImaging/Reference/CoreImageFilterReference/Reference/
    reference.html

    On that list, look at CIAffineTransform.  In fact, Take a peek at
    NSAffineTransform... perhaps you could supply some strange input
    values (negative ones) and get the desired result.

    Sorry I don't have an actual *answer*, hopefully the links will help!

    John

    John Pannell
    Positive Spin Media
    http://www.positivespinmedia.com

    On Oct 13, 2006, at 4:21 PM, Simon Raisin wrote:

    > On 10/13/06, Ricky Sharp <rsharp...> wrote:
    >>
    >>
    >> Have you looked into CoreImage?
    >
    >
    > That you for the prompt response Ricky.  I *have* looked at CI, but
    > again, I
    > must not be looking at the right things.  I see things like filters,
    > vectors, etc., but I can't seem to track down anything that
    > performs "basic"
    > tasks like rotation & flipping.
    >
    > Any specific pointers to the docs would be greatly appreciated!
  • On 13 Oct 06, at 15:50, John Pannell wrote:
    > I tried to answer your first request, but couldn't find horizontal
    > flips specifically in the core image docs.  Rotation is in there.
    > Here was what I was going to suggest:
    >
    > Example of image processing in Core Image:
    >
    > file:///Developer/ADC%20Reference%20Library/documentation/
    > GraphicsImaging/Conceptual/CoreImaging/ci_tasks/
    > chapter_3_section_4.html
    >
    > List of Apple provided CIFilters:
    >
    > file:///Developer/ADC%20Reference%20Library/documentation/
    > GraphicsImaging/Reference/CoreImageFilterReference/Reference/
    > reference.html
    >
    > On that list, look at CIAffineTransform.  In fact, Take a peek at
    > NSAffineTransform... perhaps you could supply some strange input
    > values (negative ones) and get the desired result.
    >
    > Sorry I don't have an actual *answer*, hopefully the links will help!

    Scale horizontally by a factor of -1.0 - that'll flip it across the Y-
    axis.
  • Simon-

    I think this is relatively easy directly in objective C.  At least it
    is for monochrome (greyscale) images.  I haven't ever tried it on
    colored images, but the same techniques should still work.

    For a Monochrome image, use the bitmapData method of NSBitmapImageRep
    to obtain a pointer to an array of bytes that represents the pixel-by-
    pixel brightness values of the image.  Each byte ranges from 0
    (black) to 255 (white) for that pixel.  The data is organized row-by-
    row.  You can determine the number rows with method pixelsHigh.  You
    can determine the number of bytes per row with the (duh) bytesPerRow
    method.  Note that bytesPerRow isn't the same as pixelsWide, due to
    some storage alignment issues - bytesPerRow is often larger.  Once
    you understand this structure you can directly change the contents of
    the image just by writing to values offset from the pointer to the
    bitmapData.

    Here's an example of code that does a 180 degree rotation of a
    subclassed Monochrome image.

    - (void)rotate180
    {
      int x, y, w, h, bytesPerRow ;
      unsigned char *pData ;
      unsigned char *pTop ;
      unsigned char *pBottom ;
      unsigned char byte ;

      // obtain a pointer to the monochrome/greyscale data
      pData = [self bitmapData] ;

      w = [self pixelsWide] ;
      h = [self pixelsHigh] ;
      bytesPerRow = [self bytesPerRow] ;

      // Swap the contents of the outermost rows, then the next rows,
    working from
      // top&bottom toward the middle.
      for (y = 0 ; y < h/2 ; ++y)
      {
        pTop = pData + y * bytesPerRow ;
        pBottom = pData + (h-y-1) * bytesPerRow + w - 1 ;

        for (x = 0 ; x < w ; ++x)
        {
          byte = *pTop ;
          *pTop++ = *pBottom ;
          *pBottom-- = byte ;

        }
      }
      // If the height is an odd number of rows, then we have to reverse
    the order
      // of the middle row.
      if ((h % 2) == 1)
      {
        y = h/2 ;
        pTop = pData + y * bytesPerRow ; // Actually left edge
        pBottom = pTop + w - 1 ;        // Actually right edge of the
    same row

        for (x = 0 ; x < w/2 ; ++x)
        {
          byte = *pTop ;
          *pTop++ = *pBottom ;
          *pBottom-- = byte ;
        }
      }
    } // rotate180

    This could be easily modified to make your horizontal flip.  Note
    that the last section does exactly that operation on a single row.
    You would just have to drop the first for-loop and modify the last
    major block into a loop over all of the rows (looping on y).
    A vertical flipper could also be implemented easily, by swapping
    whole rows from top and bottom.  The same technique allows you do
    operations like inverting each pixel, i.e. making a negative image.
    Just do
    value = (255-Value)
    on each pixel.

    For full color bitmaps, the problem gets more complicated, but not
    outrageously so.  The bitmap data consists of three-bytes per pixel,
    for RGB.  But there may be other variations.  And those three bytes
    can be organized in at least two ways.  One is "planar", with all the
    Red pixels first, then the Green Pixels, then the Blue pixels.
    Effectively you have three monochrome images to flip.  But the image
    could also be "meshed", stored in groups of three-bytes, for each
    pixel, alternating RGB-RGB-RGB-RGB etc.  In that case, you have to
    swap left and right pixels in each row, three bytes at a time.  You
    can tell the two types apart using method isPlaner.  And you can tell
    how many color bytes there are per pixel with method samplesPerPixel.

    So making a roll-your-own generic image flipper could take some work
    to cover all the cases.  But if you have only images of a single
    type, then you can easily do something like the above code.

    Hope that helps.
    Tom :::/
previous month october 2006 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today