objective-cnsimageviewikimageview

Save image after rotate it. But picture has lower resolution after saving


I am trying rotate an image from IKImageView. But after rotating and saving it, I got a lower resolution picture.
Below is code which I am using for rotating

-(NSImage *)imageRotated:(float)degrees{
    degrees = fmod(degrees, 360.);
    if(0 == degrees){
        return self;
    }
    NSSize size = [self size];
    NSSize maxSize;
    if(90. == degrees || 270. == degrees || -90== degrees || -270. == degrees){
        maxSize = NSMakeSize(size.height, size.width);
    }else if (180. == degrees || -180. == degrees){
        maxSize = size;
    }else{
        maxSize = NSMakeSize(20+MAX(size.width, size.height), 20+MAX(size.width, size.height));
    }

    NSAffineTransform *rot = [NSAffineTransform transform];
    [rot rotateByDegrees:degrees];
    NSAffineTransform *center = [ NSAffineTransform transform];
    [center translateXBy:maxSize.width/2 yBy:maxSize.height/2];
    [rot appendTransform:center];
    NSImage *image = [[NSImage alloc]init];
    image = [NSImage imageWithSize:maxSize flipped:NO drawingHandler:^BOOL(NSRect desRect){
            [rot concat];
            NSRect rect = NSMakeRect(0, 0, size.width, size.height);
            NSPoint corner = NSMakePoint(-size.width/2, -size.height/2);
            [self drawAtPoint:corner fromRect:rect operation:NSCompositeCopy fraction:1.0];
        return YES;
    }];
    return image;
}


then, I converted image to bitmap by below code

- (NSBitmapImageRep *)bitmapImageRepresentation{
    int width = [self size].width;
    int height = [self size].height;

    if(width <1 || height < 1)
        return nil;

    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]
                             initWithBitmapDataPlanes:NULL
                             pixelsWide:width
                             pixelsHigh:height
                             bitsPerSample:8
                             samplesPerPixel:4
                             hasAlpha:YES
                             isPlanar:NO
                             colorSpaceName:NSDeviceRGBColorSpace
                             bytesPerRow:width*4
                             bitsPerPixel:32];

    NSGraphicsContext *ctx = [NSGraphicsContext graphicsContextWithBitmapImageRep:rep];
    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:ctx];
    [self drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];
    [ctx flushGraphics];
    [NSGraphicsContext restoreGraphicsState];
    return rep;
}


and I used below code to convert to NSData, then write to file

- (NSData*)toNSData{
    NSImage *imgTemp = [[NSImage alloc]initWithSize:NSMakeSize(self.size.width*2, self.size.height*2)];
    imgTemp = self;
    NSBitmapImageRep *bmprep = [imgTemp bitmapImageRepresentation];
    NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCurrentFrame];
    NSData *pngData = [[NSData alloc]init];
    pngData = [bmprep representationUsingType:NSPNGFileType properties:imageProps];
    return pngData;
}

Could you show me the reason why picture after saving have lower resolution?.
I am using MacBook Pro (Retina, 13-inch, Mid 2014)
Thank you very much in advance :)


Solution

  • I think you are rotating the image twice.

    Inside the method rotateLeft

    //First rotation
    //Rotate Picture
            Img = [self imageRotatedByDegrees:Img and:90];
    
    //Second rotation
    [_imageView rotateImageLeft:sender];
    

    So I believe you will need to block the second rotation and you will get rid of your issue.