2013-07-14 58 views
3

我從磁盤加載圖像(NSImage),並將其繪製到MAC上的NSImageView,沒有問題的圖像看起來很好,清晰。NSImage lockFocus unlockFocus image bomes blurry

將它繪製到NSImageView後,我調用下面的函數與相同的圖像,然後將返回的值繪製到相同的NSImageView。由此產生的圖像極其模糊,即使我只做了lockFocus和UnlockFocus而沒有做其他事情。

-(NSImage*)addTarget:(NSImage*)image 
{ 
    [image lockFocus]; // this image is sharp and clear 
    [image unlockFocus]; 
    return image;  // this image is extremely blurry 
} 

任何人都知道爲什麼或如何解決這個問題?

感謝 粗糙

回答

0

要解決你的問題是困難的,因爲你不說你想要達到的目標。你爲什麼寫這種方法,你爲什麼稱它,你期望這種方法做什麼?你說:全部I do is lockFocus and UnlockFocus without doing anything else.事實上,它看起來像打電話lockFocusunlockFocus(之間沒有什麼)什麼都不做。但這是錯誤的。 [image lockFocus]獨自變化image顯着。一個NSImage對象包含類NSImageRep的零,一個(大多數情況下)或更多(圖標或某些TIFF)對象。此圖片上的電話lockFocus選擇NSImageRep,這最適合在屏幕上描繪。然後它計算出需要用給定大小渲染圖像的多少像素(但現在用於屏幕),但分辨率僅爲72 dpi(或視網膜屏幕爲144 dpi)。然後從表示列表中刪除NSImageRep,並創建一個新的NSImageRep。在以前的操作系統版本(10.6之前)中,創建了NSCachedImageRep。但是現在創建了一個NSCGImageSnapshotRep,它的底層是一個CGImage。做一個前lockFocus和一個

NSLog(@" image is:\n%@", image); 

unlockFocus調用後和你將看看會發生什麼:對高分辨率圖像的像素數會下降,這是別的一個無非質量的降低。這會讓你的圖像模糊。

1

因此,做一些研究時,我意識到這與視網膜顯示有關。我猜鎖定焦點總是會在最好的表現中得到表示,如果在計算機的任何地方都有一個視網膜顯示器,它將根據該比例因子進行渲染。因此,爲了得到這個以保持適當的尺寸和DPI我創建了一個方法,通過所有屏幕迭代並返回最大backingScaleFactor

func maximumScaleFactor(screen: NSScreen) -> CGFloat { 
    var max: CGFloat = 0 
    for s in NSScreen.screens()! { 
     if s.backingScaleFactor > max { max = s.backingScaleFactor } 
    } 
    return max/screen.backingScaleFactor 
} 

那麼對於「NSImage中」我做了以下

-(NSImage*)addTarget:(NSImage*)image 

    let scale = self.maximumScaleFactor(currentScreen) 
    let originalSize = image.size 

    //cut the image size in half 
    var size = image.size 
    size.x /= scale 
    size.y /= scale 


    image.lockFocus() 
    //do whatever drawing you need here 
    image.unlockFocus() 

    //set the image back to its original size 
    image.size = originalSize 

    return image 
} 

到目前爲止,這對我來說效果很好,圖像質量在我看來主觀上也是一樣。