2

プログラムで ICNS (1024x1024 の画像を含む) を作成しようとしています。現在NSImage、 を作成してから、適切な解像度でオブジェクトを作成CGImageRefし、最後に を使用してそれらをアイコンに追加していますCGImageDestinationAddImage()。Peter Hosey は既に '@2x' 画像の作成を手伝ってくれましたが、画像のサイズは設定したくありません。

これはコードです(まだ少し面倒ですsourcefileが、画像へのパスを表しています):

NSSize sizes[10];
sizes[0] = NSMakeSize(1024,1024);
sizes[1] = NSMakeSize(512,512);
sizes[2] = NSMakeSize(512,512);
sizes[3] = NSMakeSize(256,256);
sizes[4] = NSMakeSize(256,256);
sizes[5] = NSMakeSize(128,128);
sizes[6] = NSMakeSize(64,64);
sizes[7] = NSMakeSize(32,32);
sizes[8] = NSMakeSize(32,32);
sizes[9] = NSMakeSize(16,16);
int count = 0;
for (int i=0 ; i<10 ; i++) {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"Size%i",i+1]]) count++;
}
NSURL *fileURL = [NSURL fileURLWithPath:aPath];

// Create icns
CGImageDestinationRef dr = CGImageDestinationCreateWithURL((CFURLRef)fileURL, kUTTypeAppleICNS , count, NULL);
NSImage *img = [[NSImage alloc] initWithContentsOfFile:sourcefile];
for (int i=0 ; i<10 ; i++) {
    if ([[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"Size%i",i+1]]) {

        // Create dictionary
        BOOL is2X = true;
        if (i == 1 || i == 3 || i == 5 || i == 7 || i == 9) is2X = false;
        int dpi = 144, size = (int)(sizes[i].width/2);
        if (!is2X) {dpi = 72;size = sizes[i].width;}
        [img setSize:NSMakeSize(size,size)];
        for (NSImageRep *rep in [img representations])[rep setSize:NSMakeSize(size,size)];
        const void *keys[2] = {kCGImagePropertyDPIWidth, kCGImagePropertyDPIHeight};
        const void *values[2] = {CFNumberCreate(0, kCFNumberSInt32Type, &dpi), CFNumberCreate(0, kCFNumberSInt32Type, &dpi)};
        CFDictionaryRef imgprops = CFDictionaryCreate(NULL, keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

        // Add image
        NSRect prect = NSMakeRect(0,0,size,size);
        CGImageRef i1 = [img CGImageForProposedRect:&prect context:nil hints:nil];
        CGImageDestinationAddImage(dr, i1, imgprops);
    }
}
CGImageDestinationFinalize(dr);
CFRelease(dr);

size現在の画像の幅または高さです。dpi'@2x' 画像を作成している場合は 144、それ以外の場合は 72 です。これらの値は でチェックされていますNSLog

結果の ICNS ファイル内の画像はすべて、入力画像と同じサイズです。入力画像のサイズが 1024x1024 の場合、ImageIO は次のようにエラーを出します。

ImageIO: _CGImagePluginWriteICNS はサポートされていない画像サイズ (1024 x 1024) - 倍率: 1

dpiが72、サイズが1024x1024の場合、毎回上記エラーが表示されます。

ICNS ファイルに追加される CGImage のサイズを設定する方法を知る必要があります。


編集:画像を記録しました:

2012-12-31 12:48:51.281 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={512, 512} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={512, 512} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=1024x1024 Alpha=YES

Planar=NO Format=(まだロードされていない) CurrentBacking=nil (障害) CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.058 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={512, 512} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={512, 512} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.111 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={256, 256} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={256, 256} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.238 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={256, 256} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={256, 256} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.309 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={128, 128} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={128, 128} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.409 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={128, 128} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={128, 128} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO

Format=2 CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.534 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={32, 32} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={32, 32} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO Format=2

CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.616 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={32, 32} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={32, 32} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO Format=2

CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.729 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={16, 16} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={16, 16} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO Format=2

CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

2012-12-31 12:48:52.864 Eicon[912:680f] |NSImage 0x101b4caf0 サイズ={16, 16} 担当者=(

"NSBitmapImageRep 0x10380b900 Size={16, 16} ColorSpace=Generic RGB colorspace BPS=8 BPP=32 Pixels=1024x1024 Alpha=YES Planar=NO Format=2

CurrentBacking=|CGImageRef: 0x101c14630| CGImageSource=0x10380ae70"

)|

4

1 に答える 1

1

エラーメッセージは正しいです。IconFamily 形式でサポートされていないサイズの画像を挿入しています。具体的には、出力から:

2012-12-26 13:48:57.682 Eicon[1131:1b0f] |NSImage 0x1025233b0 Size={11.52, 11.52} Reps=( "NSBitmapImageRep 0x10421fc30 Size={11.52, 11.52} ColorSpace=(まだロードされていない) BPS=8 BPP =(未ロード) Pixels=1024x1024 Alpha=NO Planar=NO Format=(未ロード) CurrentBacking=nil (フォルト) CGImageSource=0x104221170"

11.52 ポイントは、IconFamily のどの要素に対しても有効なサイズではありません。この画像と担当者がなぜそのサイズになっているのかを調べる必要があります。

その他のいくつかのこと:

  1. 他の回答で言ったように、表現のピクセル サイズを変更する必要はありません。ピクセルサイズはそのままにしておきます。size担当者と画像の (ポイント サイズ) を設定します (できれば有効なものに)。
  2. -[NSImage initWithSize:]ドキュメントには次のように記載されています。

    (0.0, 0.0) のサイズを渡してレシーバーを初期化することは許容されます。ただし、NSImage オブジェクトを使用する前に、レシーバーのサイズをゼロ以外の値に設定する必要があります。そうしないと、例外が発生します。

    どちらのオブジェクトのサイズも設定していません。これは、行う必要があることです。(ドキュメントの約束のように、これについて例外が発生していないことに驚いています。)

他の質問で述べたように、1024 ポイントの要素はもうありません。1024 x 1024 ピクセルの要素の正しい仕様は、512 ポイント @ 2x です。これはsize(イメージと担当者の両方の) (NSSize){ 512.0, 512.0 }(ポイント) で、担当者は 1024pixelsWideと 1024pixelsHighです。


以前は重要な材料が 1 つ欠けていたようです。ここにあります。

CGImageDestination に与える CGImage には、それに関連付けられたポイント サイズがありません。NSImages と NSImageReps だけがそれを持っています。CGImage にはピクセル サイズしかありません。画像の物理的なサイズや解像度を示すものは何もありません。

与えられた CGImage が @ 1x または @ 2x のどちらであるかを CGImageDestination に伝えるには、画像の DPI を与えるディクショナリを作成する必要があります。

NSDictionary *imageProps1x = @{
    (__bridge NSString *)kCGImagePropertyDPIWidth: @72.0,
    (__bridge NSString *)kCGImagePropertyDPIHeight: @72.0,
};
NSDictionary *imageProps2x = @{
    (__bridge NSString *)kCGImagePropertyDPIWidth: @144.0,
    (__bridge NSString *)kCGImagePropertyDPIHeight: @144.0,
};

の最後の引数として正しい辞書を渡しますCGImageDestinationAddImage

于 2012-12-30T02:01:56.810 に答える