Resizing a NSImage in a Cocoa command line tool

  • I have been trying relentlessly to resize a NSImage and save it as a
    png file in a command line tool (not a windowed app, but I included
    AppKit to get NSImage support). I tried using setScalesWhenResized
    along with setSize to no avail (image is not resized when saved), and
    I also tried locking focus to another image and drawing at a smaller
    size, but that simply crashes with the following:

    2008-08-03 20:49:40.127 imagecompressor[16757:10b] _NXCreateWindow:
    error setting window property (1002)
    2008-08-03 20:49:40.132 imagecompressor[16757:10b] _NXPlaceWindow:
    error setting window shape (1002)
    2008-08-03 20:49:40.132 imagecompressor[16757:10b]
    _NSShapePlainWindow: error setting window shape (1002)
    2008-08-03 20:49:40.144 imagecompressor[16757:10b]
    PScurrentwindowbounds: CGSGetWindowBounds returned error (1002)
    Sun Aug  3 20:49:40 imagecompressor[16757] <Error>:
    CGSImageDataLockDevice: Bad device image source
    Sun Aug  3 20:49:40 imagecompressor[16757] <Error>:
    ripc_DrawWindowContents - Cannot acquire window image
    2008-08-03 20:49:40.146 imagecompressor[16757:10b] *** -
    [NSCachedImageRep representationUsingType:properties:]: unrecognized
    selector sent to instance 0x116c30
    2008-08-03 20:49:40.146 imagecompressor[16757:10b] *** Terminating app
    due to uncaught exception 'NSInvalidArgumentException', reason: '*** -
    [NSCachedImageRep representationUsingType:properties:]: unrecognized
    selector sent to instance 0x116c30'
    2008-08-03 20:49:40.146 imagecompressor[16757:10b] Stack: (
        2527650123,
        2500743419,
        2527679306,
        2527672652,
        2527672850,
        11646,
        10094
    )
    Trace/BPT trap

    I hope someone could come to my aid!
    --
    定魅刀利
    Dimitri Bouniol
    <dimitri008...>
    http://www.appkainime.com/
  • Hi Dimitri,

    The size property describes a more abstract size than pixels.  If you
    set it, you're changing the DPI of the image you write out, not how
    many pixels it has.

    It's not safe in general to use AppKit from an app that cannot connect
    to the window server ¨C see
    <http://developer.apple.com/technotes/tn2005/tn2083.html#SECLIVINGDANGEROUSL
    Y
    >.
    If you _can_ connect to the window server (i.e. this app isn't
    running headless on some machine where you aren't logged in to
    console) then you might just need to call NSApplicationLoad() in your
    main method.  This function does some AppKit global setup that is
    normally done in NSApplicationMain, but NSApplicationLoad returns
    control to you.

    That said, if you can restrict yourself to NSBitmapImageRep, that
    should work without a windowserver connection.  You can draw from your
    original bitmap into a new, smaller one like this:

    NSBitmapImageRep *newBitmap = [[NSBitmapImageRep alloc]
    initWithBitmapDataPlanes:NULL pixelsWide:pixelsWide
    pixelsHigh:pixelsHigh bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES
    isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace
    bitmapFormat:NSAlphaFirstBitmapFormat bytesPerRow:0 bitsPerPixel:32];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:[NSGraphicsContext
    graphicsContextWithBitmapImageRep:newBitmap]];
    [oldBitmap drawInRect:NSMakeRect(0,0,pixelsWide,pixelsHigh)];
    [NSGraphicsContext restoreGraphicsState];

    and write it to png data with -[NSBitmapImageRep
    representationUsingType:properties:].

    Also, the technote I referenced above doesn't mention that the
    CoreGraphics framework is daemon safe, which it is.

    -Ken
    Cocoa Frameworks

    On Tue, Aug 5, 2008 at 2:44 AM, Dimitri Bouniol <dimitri008...> wrote:
    > I have been trying relentlessly to resize a NSImage and save it as a png
    > file in a command line tool (not a windowed app, but I included AppKit to
    > get NSImage support). I tried using setScalesWhenResized along with setSize
    > to no avail (image is not resized when saved), and I also tried locking
    > focus to another image and drawing at a smaller size, but that simply
    > crashes with the following:
    >
    > 2008-08-03 20:49:40.127 imagecompressor[16757:10b] _NXCreateWindow: error
    > setting window property (1002)
    > 2008-08-03 20:49:40.132 imagecompressor[16757:10b] _NXPlaceWindow: error
    > setting window shape (1002)
    > 2008-08-03 20:49:40.132 imagecompressor[16757:10b] _NSShapePlainWindow:
    > error setting window shape (1002)
    > 2008-08-03 20:49:40.144 imagecompressor[16757:10b] PScurrentwindowbounds:
    > CGSGetWindowBounds returned error (1002)
    > Sun Aug  3 20:49:40 imagecompressor[16757] <Error>: CGSImageDataLockDevice:
    > Bad device image source
    > Sun Aug  3 20:49:40 imagecompressor[16757] <Error>: ripc_DrawWindowContents
    > - Cannot acquire window image
    > 2008-08-03 20:49:40.146 imagecompressor[16757:10b] *** -[NSCachedImageRep
    > representationUsingType:properties:]: unrecognized selector sent to instance
    > 0x116c30
    > 2008-08-03 20:49:40.146 imagecompressor[16757:10b] *** Terminating app due
    > to uncaught exception 'NSInvalidArgumentException', reason: '***
    > -[NSCachedImageRep representationUsingType:properties:]: unrecognized
    > selector sent to instance 0x116c30'
    > 2008-08-03 20:49:40.146 imagecompressor[16757:10b] Stack: (
    > 2527650123,
    > 2500743419,
    > 2527679306,
    > 2527672652,
    > 2527672850,
    > 11646,
    > 10094
    > )
    > Trace/BPT trap
    >
    > I hope someone could come to my aid!
    > --
    > ¶¨÷ȵ¶Àû
    > Dimitri Bouniol
    > <dimitri008...>
    > http://www.appkainime.com/
    >
  • Thank you very much - that worked perfectly.

    On Aug 5, 2008, at 7:20 AM, Ken Ferry wrote:

    > Hi Dimitri,
    >
    > The size property describes a more abstract size than pixels.  If you
    > set it, you're changing the DPI of the image you write out, not how
    > many pixels it has.
    >
    > It's not safe in general to use AppKit from an app that cannot connect
    > to the window server ¨C see
    > <http://developer.apple.com/technotes/tn2005/tn2083.html#SECLIVINGDANGEROUSL
    Y
    > >.
    > If you _can_ connect to the window server (i.e. this app isn't
    > running headless on some machine where you aren't logged in to
    > console) then you might just need to call NSApplicationLoad() in your
    > main method.  This function does some AppKit global setup that is
    > normally done in NSApplicationMain, but NSApplicationLoad returns
    > control to you.
    >
    > That said, if you can restrict yourself to NSBitmapImageRep, that
    > should work without a windowserver connection.  You can draw from your
    > original bitmap into a new, smaller one like this:
    >
    > NSBitmapImageRep *newBitmap = [[NSBitmapImageRep alloc]
    > initWithBitmapDataPlanes:NULL pixelsWide:pixelsWide
    > pixelsHigh:pixelsHigh bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES
    > isPlanar:NO colorSpaceName:NSCalibratedRGBColorSpace
    > bitmapFormat:NSAlphaFirstBitmapFormat bytesPerRow:0 bitsPerPixel:32];
    > [NSGraphicsContext saveGraphicsState];
    > [NSGraphicsContext setCurrentContext:[NSGraphicsContext
    > graphicsContextWithBitmapImageRep:newBitmap]];
    > [oldBitmap drawInRect:NSMakeRect(0,0,pixelsWide,pixelsHigh)];
    > [NSGraphicsContext restoreGraphicsState];
    >
    > and write it to png data with -[NSBitmapImageRep
    > representationUsingType:properties:].
    >
    > Also, the technote I referenced above doesn't mention that the
    > CoreGraphics framework is daemon safe, which it is.
    >
    > -Ken
    > Cocoa Frameworks
    >
    > On Tue, Aug 5, 2008 at 2:44 AM, Dimitri Bouniol <dimitri008...>
    > wrote:
    >> I have been trying relentlessly to resize a NSImage and save it as
    >> a png
    >> file in a command line tool (not a windowed app, but I included
    >> AppKit to
    >> get NSImage support). I tried using setScalesWhenResized along with
    >> setSize
    >> to no avail (image is not resized when saved), and I also tried
    >> locking
    >> focus to another image and drawing at a smaller size, but that simply
    >> crashes with the following:
    >>
    >> 2008-08-03 20:49:40.127 imagecompressor[16757:10b] _NXCreateWindow:
    >> error
    >> setting window property (1002)
    >> 2008-08-03 20:49:40.132 imagecompressor[16757:10b] _NXPlaceWindow:
    >> error
    >> setting window shape (1002)
    >> 2008-08-03 20:49:40.132 imagecompressor[16757:10b]
    >> _NSShapePlainWindow:
    >> error setting window shape (1002)
    >> 2008-08-03 20:49:40.144 imagecompressor[16757:10b]
    >> PScurrentwindowbounds:
    >> CGSGetWindowBounds returned error (1002)
    >> Sun Aug  3 20:49:40 imagecompressor[16757] <Error>:
    >> CGSImageDataLockDevice:
    >> Bad device image source
    >> Sun Aug  3 20:49:40 imagecompressor[16757] <Error>:
    >> ripc_DrawWindowContents
    >> - Cannot acquire window image
    >> 2008-08-03 20:49:40.146 imagecompressor[16757:10b] *** -
    >> [NSCachedImageRep
    >> representationUsingType:properties:]: unrecognized selector sent to
    >> instance
    >> 0x116c30
    >> 2008-08-03 20:49:40.146 imagecompressor[16757:10b] *** Terminating
    >> app due
    >> to uncaught exception 'NSInvalidArgumentException', reason: '***
    >> -[NSCachedImageRep representationUsingType:properties:]: unrecognized
    >> selector sent to instance 0x116c30'
    >> 2008-08-03 20:49:40.146 imagecompressor[16757:10b] Stack: (
    >> 2527650123,
    >> 2500743419,
    >> 2527679306,
    >> 2527672652,
    >> 2527672850,
    >> 11646,
    >> 10094
    >> )
    >> Trace/BPT trap
    >>
    >> I hope someone could come to my aid!

    --
    ¶¨÷ȵ¶Àû
    Dimitri Bouniol
    <dimitri008...>
    http://www.appkainime.com/
previous month august 2008 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