mr.Pony
mr.Pony

Reputation: 257

NSImage become blurry after transformation

I rotated a NSImage at its center with the NSAffineTransform class and it works. The code is here:

- (NSImage*)rotateImage: (NSImage*)myImage angle:(float)rotateAngle {

    NSRect imageBounds = {NSZeroPoint, [myImage size]};
    NSRect transformedImageBounds = imageBounds;
    NSBezierPath* boundsPath = [NSBezierPath bezierPathWithRect:imageBounds];
    NSAffineTransform* transform = [NSAffineTransform transform];

    // calculate the bounds for the rotated image
    if (rotateAngle != 0) {

        NSAffineTransform* temptransform = [NSAffineTransform transform];
        [temptransform rotateByDegrees:rotateAngle];
        [boundsPath transformUsingAffineTransform:temptransform];

        NSRect rotatedBounds = {NSZeroPoint, [boundsPath bounds].size};

        // center the image within the rotated bounds
        imageBounds.origin.x += (NSWidth(rotatedBounds) - NSWidth (imageBounds))/2;
        imageBounds.origin.y += (NSHeight(rotatedBounds) - NSHeight (imageBounds))/2;

        // set up the rotation transform
        [transform translateXBy:+(NSWidth(rotatedBounds) / 2) yBy:+ (NSHeight(rotatedBounds) / 2)];
        [transform rotateByDegrees:rotateAngle];
        [transform translateXBy:-(NSWidth(rotatedBounds) / 2) yBy:- (NSHeight(rotatedBounds) / 2)];

        transformedImageBounds = rotatedBounds;
    }

    // draw the original image into the new image
    NSImage* transformedImage = [[NSImage alloc] initWithSize:transformedImageBounds.size];;
    [transformedImage lockFocus];
    [transform concat];
    [myImage drawInRect:imageBounds fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0] ;

    [transformedImage unlockFocus];

    return transformedImage;
}

But the quality of the resulted image is very bad. How to solve it?

Some say the "lockFocus" methods caused this but I hv no idea of how to do this without using the method.

Upvotes: 0

Views: 933

Answers (1)

James Williams
James Williams

Reputation: 1891

I'm not sure what it's place is in this pipeline, but if you can get hold of the NSGraphicsContext (which might be as easy as:

NSGraphicsContext *myContext = [NSGraphicsContext currentContext];

after your lockFocus), you can try

[myContext setImageInterpolation:NSImageInterpolationHigh]

to ask Cocoa to use its best algorithms for scaling the image. If you switch to using the CGImageRef API, I know you can get more control over the interpolation setting pretty easily.

Upvotes: 1

Related Questions