Создание ICNS программно: "Неподдерживаемый размер изображения"
Я пытаюсь создать ICNS (включая изображение 1024x1024) программно. В настоящее время я создаю NSImage
тогда я создаю CGImageRef
объекты с соответствующим разрешением, наконец, я добавляю их к значку, используя CGImageDestinationAddImage()
, Питер Хоси уже помог мне создать изображения с разрешением @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
равно 144, если мы создаем изображение "@2x", в противном случае - 72. Эти значения были проверены с помощью NSLog
,
Все изображения в итоговом файле ICNS имеют тот же размер, что и входное изображение. Если размер входного изображения 1024x1024, ImageIO жалуется:
ImageIO: _CGImagePluginWriteICNS неподдерживаемый размер изображения (1024 x 1024) - коэффициент масштабирования: 1
Вышеуказанная ошибка отображается каждый раз, когда dpi составляет 72, а размер составляет 1024x1024.
Мне нужно знать, как установить размер CGImage, который должен быть добавлен в файл ICNS.
РЕДАКТИРОВАТЬ: я записал изображения:
2012-12-31 12: 48: 51.281 Eicon [912: 680f] | NSImage 0x101b4caf0 Size = {512, 512} Reps =(
"NSBitmapImageRep 0x10380b900 Size={512, 512} ColorSpace=(not yet loaded) BPS=8 BPP=(not yet loaded) Pixels=1024x1024 Alpha=YES
Планарный = НЕТ Формат =(еще не загружен) CurrentBacking= ноль (сбой) CGImageSource = 0x10380ae70 "
) |
2012-12-31 12: 48: 52.058 Eicon [912: 680f] | NSImage 0x101b4caf0 Size = {512, 512} Reps =(
"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 Size = {256, 256} Reps =(
"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 Size = {256, 256} Reps =(
"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 Size = {128, 128} Reps =(
"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 Size = {128, 128} Reps =(
"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 Size = {32, 32} Reps =(
"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 Size = {32, 32} Reps =(
"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 Size = {16, 16} Reps =(
"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 Size = {16, 16} Reps =(
"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"
) |
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= ноль (сбой) CGImageSource = 0x104221170 "
11,52 балла не является допустимым размером для любого элемента IconFamily. Вам нужно выяснить, почему это изображение и репутация имеют такой размер.
Пара других вещей:
- Как я уже говорил в этом другом ответе, вам не нужно изменять размер пикселя представления. Оставьте размер пикселя в покое. Установить
size
(размер точки) представителя и изображения (желательно для чего-то действительного). -[NSImage initWithSize:]
Документация гласит:Допустимо инициализировать приемник, передавая размер (0,0, 0,0); однако размер получателя должен быть установлен в ненулевое значение, прежде чем будет использован объект NSImage, иначе будет сгенерировано исключение.
Вы не устанавливаете размер любого объекта, что вам и нужно сделать. (Я удивлен, что вы не получите исключения по этому поводу, как обещания документации.)
Как я уже упоминал в вашем другом вопросе, больше нет 1024-балльного элемента; правильная спецификация для элемента размером 1024 х 1024 пикселя равна 512 точкам при 2х. Это size
(как изображения, так и представителя) (NSSize){ 512.0, 512.0 }
(баллы), с повторением 1024 pixelsWide
и 1024 pixelsHigh
,
Похоже, мне не хватало одного ключевого ингредиента раньше. Вот.
CGImage, который вы даете CGImageDestination, не имеет размера точки, ассоциированного с ним, только с NSImages и NSImageReps. CGImage имеет только размер в пикселях; ничего не указывает на физический размер изображения или разрешение.
Чтобы сообщить CGImageDestination, должен ли данный CGImage быть @ 1x или @ 2x, вам нужно создать словарь, который дает 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
,