CGサムネイル作成用の辞書を作成する際に、値をintに直接マップすると、完全に機能します。
NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
[NSNumber numberWithInt:56], kCGImageSourceThumbnailMaxPixelSize,
nil];
.
.
.
.
.
CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (CFDictionaryRef)d);
次に、その値(56)をインターフェイスで変更できるプロパティに変更できるようにしたいので、ヘッダーにintを作成します。
my.h
int thumbSize;
//within my init method Iinitialize it:
thumbSize = 56;
//then I change the reference in the dictionary:
NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
[NSNumber numberWithInt:thumbSize], kCGImageSourceThumbnailMaxPixelSize,
nil];
これを行うと、次のエラーでクラッシュします。
3月25日11:39:49Charles-Romestants-MacBook.localPhotoMosaic [3583]:ImageIO:CGImageSourceCreateWithDataデータパラメータはnilです
3月25日11:39:49Charles-Romestants-MacBook.localPhotoMosaic [3583]:ImageIO:CGImageSourceCreateImageAtIndex画像ソースパラメータはnilです
2013-03-25 11:39:49.197 PhotoMosaic [3583:707] ***-[__ NSArrayM insertObject:atIndex:]:オブジェクトをnilにすることはできません
2013-03-25 11:39:49.201 PhotoMosaic [3583:707](
0 CoreFoundation 0x00007fff912ccb06 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8bc833f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff9127d27a-[__ NSArrayM insertObject:atIndex:] + 282
3 PhotoMosaic 0x00000001000023bf-[BlendingView setMosaicImages:] + 1071
4 PhotoMosaic 0x0000000100003034-[Controller createMosaic:] + 84
5 AppKit 0x00007fff8ec3d989-[NSApplication sendAction:to:from:] + 342
6 AppKit 0x00007fff8ec3d7e7-[NSControl sendAction:to:] + 85
7 AppKit 0x00007fff8ec3d71b-[NSCell _sendActionFrom:] + 138
8 AppKit 0x00007fff8ec3bc03-[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 1855
9 AppKit 0x00007fff8ec3b451-[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 504
10 AppKit 0x00007fff8ec3abcc-[NSControl mouseDown:] + 820
11 AppKit 0x00007fff8ec3253e-[NSWindow sendEvent:] + 6853
12 AppKit 0x00007fff8ec2e674-[NSApplication sendEvent:] + 5761
13 AppKit 0x00007fff8eb4424a-[NSApplication run] + 636
14 AppKit 0x00007fff8eae8c06 NSApplicationMain + 869
15PhotoMosaic0x0000000100001d52メイン+34
16PhotoMosaic0x0000000100001d24開始+52
)。
これはなぜですか、NSNumber+numberWithIntをintに渡します...
[編集]メソッド全体を追加する:
-(void)setMosaicImages:(NSMutableArray *)_mosaicImages
{
NSLog(@"Entering here in setMosaicImages, we have %lu images",_mosaicImages.count);
mosaicImages = _mosaicImages;
CGImageSourceRef source;
source = CGImageSourceCreateWithData((CFDataRef)[canvasImage TIFFRepresentation], NULL);
CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(NULL,
CGImageGetWidth(image), CGImageGetHeight(image),
8, CGImageGetWidth(image) * 4,
colorspace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorspace);
NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
[NSNumber numberWithInt:thumbSize], kCGImageSourceThumbnailMaxPixelSize,
nil];
//thumbSize is declared in.h and initialized in init method with a value of 56 (int thumbSize; then thumbSize = 56; if I change the parameter to literal 56 it works.
//create NSMUTABLE array with thumbnails for each mosaic image
mosaicCGThumbs = [[NSMutableArray alloc]initWithCapacity:mosaicCGThumbs.count];
NSURL* url;
for(int i=0; i<mosaicImages.count;i++)
{
url = [NSURL fileURLWithPath:[(myImageObject *)[mosaicImages objectAtIndex:i] getPath]];
CGImageSourceRef src = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (CFDictionaryRef)d);
[mosaicCGThumbs addObject:imref];
CGImageRelease(imref);
}
CGRect r;
CGImageRef thumbRef;
int x_offset=0;
int y_offset = 0;
while(y_offset < CGImageGetHeight(image))
{
while (x_offset<CGImageGetWidth(image))
{
thumbRef = (CGImageRef)[mosaicCGThumbs objectAtIndex:arc4random() % mosaicCGThumbs.count];
r = CGRectMake(x_offset, y_offset, CGImageGetWidth(thumbRef), CGImageGetHeight(thumbRef));
CGContextSetBlendMode(ctx, kCGBlendModeCopy);
CGContextDrawImage(ctx, r, thumbRef);
x_offset+=CGImageGetWidth(thumbRef);
}
x_offset=0;
y_offset+=56;
}
NSLog(@"Finished Drawing Mosaic BG");
image = CGBitmapContextCreateImage(ctx);
//
// CIImage* newImage = [[[CIImage alloc] initWithCGImage:image] autorelease];
// CGImageRelease(image);
CGContextRelease(ctx);
canvasImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize];
mosaicPresent=YES;
[self setNeedsDisplay:YES];
}
デバッグ目的でさらに情報を追加する:
作成したNSDictionaryと何が違うのか見てみることにしたので
次のコードと、検査するブレークポイントを追加しました。
NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
[NSNumber numberWithInt:thumbSize], kCGImageSourceThumbnailMaxPixelSize,
nil];
NSDictionary* d2 = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
(id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
[NSNumber numberWithInt:56], kCGImageSourceThumbnailMaxPixelSize,
nil];
デバッガーでそれを見ると、私はこれを取得します:(サムニールのピクセルサイズの値が2つでどのように異なるかを確認してください。これについて詳しく調べます。
(gdb)po d
{{
kCGImageSourceCreateThumbnailFromImageAlways = 1;
kCGImageSourceCreateThumbnailWithTransform = 1;
kCGImageSourceShouldAllowFloat = 1;
kCGImageSourceThumbnailMaxPixelSize = 0;
}
(gdb)po d2
{{
kCGImageSourceCreateThumbnailFromImageAlways = 1;
kCGImageSourceCreateThumbnailWithTransform = 1;
kCGImageSourceShouldAllowFloat = 1;
kCGImageSourceThumbnailMaxPixelSize = 56;
}