Тонкія белыя лініі дадаюцца пры абрэзцы выявы (Objective-C OSX) (Thin white lines being added when cropping an image (Objective-C OSX))


問題描述

Тонкія белыя лініі дадаюцца пры абрэзцы выявы (Objective‑C OSX) (Thin white lines being added when cropping an image (Objective‑C OSX))

I am cutting up a large image and saving it into many different images. I first implemented this in iOS and it is working fine, but when I try and port the code to OSX, a thin white line (1 pixel) appears on the top and right of the image. The line is not pure white, or solid (see sample below).

Here is the iOS code to make one sub‑image, that works like a champ:

‑(void)testMethod:(int)page forRect:(CGRect)rect{
    NSString *filePath = @"imageName";

    NSData *data = [HeavyResourceManager dataForPath:filePath];//this just gets the image as NSData
    UIImage *image = [UIImage imageWithData:data];

    CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], rect);//crop in the rect

    UIImage *result = [UIImage imageWithCGImage:imageRef scale:0 orientation:image.imageOrientation];
    CGImageRelease(imageRef);

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [paths objectAtIndex:0];

    [UIImageJPEGRepresentation(result, 1.0) writeToFile:[documentsDirectoryPath stringByAppendingPathComponent::@"output.jpg"] atomically:YES];
}

Here is the ported code in OSX that causes the white lines to be added:

NSImage *source = [[[NSImage alloc]initWithContentsOfFile:imagePath] autorelease];
//init the image
NSImage *target = [[[NSImage alloc]initWithSize:panelRect.size] autorelease];
//start drawing
[target lockFocus];
[source drawInRect:NSMakeRect(0,0,panelRect.size.width,panelRect.size.height)
          fromRect:NSMakeRect(panelRect.origin.x , source.size.height ‑ panelRect.origin.y ‑ panelRect.size.height, panelRect.size.width, panelRect.size.height)
         operation:NSCompositeCopy
          fraction:1.0];
[target unlockFocus];

//create a NSBitmapImageRep
NSBitmapImageRep *bmpImageRep = [[[NSBitmapImageRep alloc]initWithData:[target TIFFRepresentation]] autorelease];
//write to tiff
[[target TIFFRepresentation] writeToFile:@"outputImage.tiff" atomically:NO];
[target addRepresentation:bmpImageRep];     
NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:1.0] forKey:NSImageCompressionFactor];

//get the data from the representation
NSData *data = [bmpImageRep representationUsingType: NSJPEGFileType
                                             properties: imageProps];

//write the data to a file
[data writeToFile: @"outputImage.jpg" atomically:NO];

data = [bmpImageRep representationUsingType: NSPNGFileType properties: imageProps];

//write the data to png
[data writeToFile: @"outputImage.png" atomically:NO];

The above code saves the image to three different formats to check if the problem was not in the save process of a specific format. It does not seem to be because all the formats have the same problem.

Here is a blown up (4x) version of top right hand corner of the images:

(OSX, note the white line top and left. It looks like a blur here, because the image is blown up)


(iOS, note there are no white lines)

If someone could tell me why this might be happening, I would be very happy. Perhaps it has something to do with the quality difference (the OSX version seems lower quality ‑ though you can't notice)? Perhaps there is a completely different way to do this?

For reference, here is the unscaled osx image:


Update: Thanks to Daij‑Djan, I was able to stop the drawInRect method from antialiasing:

    //start drawing on target
    [target lockFocus];
    [NSGraphicsContext saveGraphicsState];
    [[NSGraphicsContext currentContext]
            setImageInterpolation:NSImageInterpolationNone];
    [[NSGraphicsContext currentContext] setShouldAntialias:NO];

    //draw the portion of the source image on target image
    [source drawInRect:NSMakeRect(0,0,panelRect.size.width,panelRect.size.height)
              fromRect:NSMakeRect(panelRect.origin.x , source.size.height ‑ panelRect.origin.y ‑ panelRect.size.height, panelRect.size.width, panelRect.size.height)
             operation:NSCompositeDestinationAtop
              fraction:1.0];

    [NSGraphicsContext restoreGraphicsState];
    //end drawing
    [target unlockFocus];

Update: Changed 'Interpolation' to NSImageInterpolationNone, as this gives a better representation. The high interpolation makes minor adjustments, which is noticeable when zooming in on text. Removing interpolation stops pixels from jumping around, but still, there is a little difference in the color (164 to 155 for a grey color). Would be great to be able to just cut up an image like I can in iOS...

‑‑‑‑‑

參考解法

方法 1:

it looks like antialiasing... you gotta round the float values you calculate when cutting/scaling the image.

use froundf() on the float values

(by lindon foxDaij‑Djan)

參考文件

  1. Thin white lines being added when cropping an image (Objective‑C OSX) (CC BY‑SA 3.0/4.0)

#objective-c #crop #nsimage #macos






相關問題

為什麼 NSWindow 或 NSView 實例處理它自己的鍵事件,而不是它的委託? (Why does an NSWindow or NSView instance handle its own key events, and not its delegate?)

在調用之前釋放了 didFinishSelector ASIHTTPRequest 的自定義委託類 (Custom delegate class for didFinishSelector ASIHTTPRequest being deallocated before called)

通過 IKImage 視圖預覽圖像 (Previewg images via IKImage View)

Gaya Jendela Kustom di Kakao (Custom Window Style in Cocoa)

Тонкія белыя лініі дадаюцца пры абрэзцы выявы (Objective-C OSX) (Thin white lines being added when cropping an image (Objective-C OSX))

Obj-C:遞歸:在堆棧上創建新對像或使用可變性 (Obj-C: Recursion: Making new objects on stack or use mutability)

XCode 4.6 顯示方法 + (void)beginAnimations:(NSString *)animationID context:(void *)context; 的內存洩漏警告 (XCode 4.6 shows a warning of memory leak for method + (void)beginAnimations:(NSString *)animationID context:(void *)context;)

單元格中不可見的 UITextField 已將 userInteractionEnabled 設置為 No (UITextField in cell that is not visible has userInteractionEnabled set to No)

Gửi nhật ký sự cố ứng dụng / nhật ký ứng dụng thông thường (Send app crash logs/regular app logs)

我的鍵盤默認值僅在我的應用程序中更改 (My keyboard default be change in only my App)

在復選框上單擊獲取表行 ID - 目標 c (On check box click get the table Row ID - Objective c)

iPhone SDK:檢查 UITableView 中每個對象的 ID 號並相應地更改徽章號 (iPhone SDK: Checking the ID number for each object in a UITableView and change the badge number accordingly)







留言討論