Re: Doubled Pixels
Re: Doubled Pixels
- Subject: Re: Doubled Pixels
- From: Graham Cox <email@hidden>
- Date: Sun, 25 Jun 2017 12:29:01 +1000
> On 24 Jun 2017, at 4:46 pm, Gerriet M. Denkmann <email@hidden> wrote:
>
>> By making the NSBitMapRepresentation yourself, creating a context for it,
>> drawing to that.
>> —Graham
>
> You severely underestimate the depth of my ignorance. It took me half a day
> to fathom your (for me) cryptic remarks.
> But thanks a lot for pointing me in the right direction!
Ah, sorry about that. I erred on the side of sketching a solution - ‘not
teaching my grandmother to suck eggs’ (though I’ve never understood why
grandmothers are supposed to be so good at that).
> This is what I did come up with (all error handling removed) (things I am
> not quite sure are marked with “??”).
> If there is anything I am doing wrong (or could do better) please tell me:
>
>
> - (NSData *)subImagePngDataWithRect: (NSRect)subRect useColour:
> (BOOL)useColour
> {
> // 1. create newSubRep (NSBitmapImageRep)
>
> NSString *colorSpaceName = useColour ? NSDeviceRGBColorSpace :
> NSDeviceWhiteColorSpace; // ??
You could get the colorSpaceName from the source image and use that. If there’s
no conversion needed between the images it’ll probably be faster (though seems
you are giving yourself the option of creating a grayscale version here).
> NSInteger samplesPerPixel = useColour ? 4 : 2;
>
> NSInteger pixelsWide = (NSInteger)ceil(subRect.size.width);
> NSInteger pixelsHigh = (NSInteger)ceil(subRect.size.height);
> NSInteger bitsPerSample = 8;
> NSInteger bitsPerPixel = samplesPerPixel * bitsPerSample;
> NSInteger bytesPerRow = pixelsWide * bitsPerPixel / 8;
>
In fact you can pass 0 for these last two and the function will calculate them
for you. It’s better to do that because if there’s the slightest thing wrong
with the parameters it will give up with an exception.
The internal calculation can also round up bytesPerRow to something that will
optimise copying performance.
> // there is another initializer with bitmapFormat - don't know
> what to use
Unless you need a specific bitmap format, don’t worry about the other one.
> NSBitmapImageRep *newSubRep = [ [NSBitmapImageRep alloc]
> initWithBitmapDataPlanes: NULL
>
> pixelsWide: pixelsWide
>
> pixelsHigh: pixelsHigh
>
> bitsPerSample: bitsPerSample
>
> samplesPerPixel: samplesPerPixel
>
> hasAlpha: YES
>
> isPlanar: NO //
>
> colorSpaceName:
> colorSpaceName
>
> bytesPerRow: bytesPerRow
>
> bitsPerPixel: bitsPerPixel
> ];
>
>
> // 2. create context (NSGraphicsContext) from newSubRep and
> make it current
>
> NSGraphicsContext *context = [ NSGraphicsContext
> graphicsContextWithBitmapImageRep: newSubRep ];
> [ NSGraphicsContext setCurrentContext: context ];
You may want to save and restore the current context around this, just to be
sure your method isn’t going to have the unwanted side effect of changing the
current context. It’s likely OK, but better safe than sorry.
>
>
> // 3. draw allRep (NSBitmapImageRep) to currentContext
>
> NSBitmapImageRep *allRep = (NSBitmapImageRep
> *)self.image.representations.firstObject;
> NSRect destRect = NSZeroRect; destRect.size = subRect.size;
Just use NSZeroRect for destRect. This is interpreted to mean “the size of the
destination image”, which is already <subRect>, rounded up. If you set the size
here and it’s not a whole number for some reason, there is the potential for
the very edge pixels not to get set, leaving a visible edge at the right and
bottom of the result.
> BOOL ok = [ allRep drawInRect: destRect
> fromRect: subRect
> operation:
> NSCompositingOperationCopy
> fraction:
> 1
> respectFlipped: NO //
> ??
> hints: nil
> ];
>
>
> // 4. get pngData from newSubRep
>
> return [ newSubRep representationUsingType: NSPNGFileType properties:
> @{} ];
> }
>
> Gerriet.
Otherwise, looks good. Does it do the job?
—Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden