4

大きな画像を切り取り、さまざまな画像に保存しています。これを最初に に実装し、iOS正常に動作していますが、コードを に移植しようとOSXすると、画像の上部と右側に細い白い線 (1 ピクセル) が表示されます。線は真っ白でも実線でもありません (下のサンプルを参照)。

以下は、iOSチャンピオンのように機能する 1 つのサブイメージを作成するコードです。

-(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];
}

以下は、移植されたコードでOSX、白い線が追加されます。

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];

上記のコードは、画像を 3 つの異なる形式で保存して、問題が特定の形式の保存プロセスにないかどうかを確認します。すべてのフォーマットに同じ問題があるためではないようです。

画像の右上隅を拡大 (4 倍) したものを次に示します。

OSX、上と左の白い線に注意してください

(OSX、左上の白い線に注意してください。画像が拡大されているため、ここではぼやけて見えます)


iOS、白線がないことに注意してください

(iOS、白線がないことに注意してください)

なぜこれが起こっているのか誰かが教えてくれたら、とてもうれしいです. おそらく、品質の違いと関係がありますか(OSXバージョンは品質が低いようですが、気付かないでしょう)?おそらく、これを行うにはまったく別の方法がありますか?

参考までに、スケーリングされていない osx イメージを次に示します。

OSX イメージのオリジナル


更新: Daij-Djan のdrawInRectおかげで、メソッドのアンチエイリアシングを停止できました。

    //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];

更新: 'Interpolation' をNSImageInterpolationNoneに変更しました。これにより、より適切な表現が得られます。補間を高くすると微調整が行われますが、これはテキストを拡大するときに顕著です。補間を削除すると、ピクセルがジャンプしなくなりますが、それでも色に少し違いがあります (灰色の場合は 164 から 155)。iOSでできるように画像を切り取ることができれば素晴らしいでしょう...

4

1 に答える 1

4

アンチエイリアシングのように見えます...画像をカット/スケーリングするときに計算する浮動小数点値を丸める必要があります。

float 値で froundf() を使用する

于 2012-11-29T07:07:47.163 に答える