2

Cocoa アプリ内からいくつかの PNG ファイルのサイズを変更しています。ファイルは最終的に別のアプリによって OpenGL テクスチャとして読み込まれ、適切に記述されていないシェーダーが適用されます。このシェーダーは、ある時点で次のことを行います。

texColor = mix(constant,vec4(texColor.rgb/texColor.a,texColor.a),texColor.a);

アルファで除算するのは悪い考えです。解決策は、そのステップで texColor の RGB コンポーネントが 1 を超えないようにすることです。しかし! 好奇心のために:

元の PNG (GIMP で作成) は驚くほど正常に動作し、GIMP で作成されたサイズ変更されたバージョンも正常に動作します。ただし、以下のコードを使用してファイルのサイズを変更すると、透過ピクセルの近くでテクスチャがギザギザになりpercentます1.0。これらの画像を無意識のうちに変更していて、突然シェーダーのバグが発生する原因が何か分かりますか?

NSImage* originalImage = [[NSImage alloc] initWithData:[currentFile regularFileContents]];
NSSize newSize = NSMakeSize([originalImage size].width * percent, [originalImage size].height * percent);
NSImage* resizedImage = [[NSImage alloc] initWithSize:newSize];
[resizedImage lockFocus];
[originalImage drawInRect:NSMakeRect(0,0,newSize.width,newSize.height)
                 fromRect:NSMakeRect(0,0,[originalImage size].width, [originalImage size].height)
                operation:NSCompositeCopy fraction:1.0];
[resizedImage unlockFocus];

NSBitmapImageRep* bits = [[[NSBitmapImageRep alloc] initWithCGImage:[resizedImage CGImageForProposedRect:nil context:nil hints:nil]] autorelease];
NSData* data = [bits representationUsingType:NSPNGFileType properties:nil];
NSFileWrapper* newFile = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease];

[newFile setPreferredFilename:currentFilename];
[folder removeFileWrapper:currentFile];
[folder addFileWrapper:newFile];

[originalImage release];
[resizedImage release];
4

2 に答える 2

0

このようなサイズ変更操作を行うときは、通常、画像の補間を高く設定します。これはあなたの問題かもしれません。

[resizedImage lockFocus];
[NSGraphicsContext saveGraphicsState];
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
[originalImage drawInRect:...]
[NSGraphicsContext restoreGraphicsState];
[resizedImage unlockFocus];

役に立たないかもしれませんが、あなたがやっていることを確認するためのもう一つのこと(下記参照):

[[NSGraphicsContext currentContext] setShouldAntialias:YES];

ターゲットの背景を知らずにアンチエイリアスを実行できないため、これで修正できない場合があります。しかし、それでも役立つかもしれません。これが問題である場合(これをすぐにアンチエイリアスできない場合)、最終的な画像を描画する準備ができた時点で、このサイズ変更を合成する必要がある場合があります。

于 2012-05-27T20:35:05.137 に答える
0

ソース PNG の DPI は?size元の画像はピクセル単位ですsizeが、ポイント単位であると想定して、2 番目の画像を作成しています。

450 ピクセル x 100 ピクセル、DPI が 300 のイメージがあるとします。このイメージは、実際の単位では 1 1/2 インチ x 1/3 インチです。

現在、Cocoa のポイントは公称 1/72 インチです。画像のポイント単位のサイズは 108 x 24 です。

その後、そのサイズに基づいて新しい画像を作成する場合、DPI は指定されていないため、ポイントごとに 1 ピクセルが想定されます。はるかに小さな画像を作成しています。つまり、細かい特徴をより粗く近似する必要があります。

元の画像の画像表現の 1 つを選択し、その値pixelsWidepixelsHigh値を使用すると、運が良くなります。ただし、これを行うと、新しい画像は元の画像とは異なる実際のサイズになります。私の例では、オリジナルは 1 1/2 x 1/3 インチでした。新しい画像のピクセル寸法は同じ (450 x 100) ですが、72 dpi であるため、6.25 x 1.39 インチになります。sizeこれを修正するには、新しいビットマップ表現のポイント数を元のポイント数に設定する必要がありますsize

于 2012-05-28T06:42:48.230 に答える