我正在構建一個Cocoa應用程序來幫助我組織數以萬計的數字圖片。它旨在保持一個非常精簡的信息數據庫,以便我可以找到我想要的圖像,然後我可以到存儲器中保存實際圖像(刻錄到DVD或CD)。我可以瀏覽圖片並設置評分,標籤等。然後我將這些數據存儲在我的硬盤上,數據庫本身的數量小於幾十張。在我的數據庫中,我想存儲一個縮略圖圖像(這會使其大約增加10倍)。我玩過幾種技術,並且使用JPEG-2000格式最小,但它看起來不能正確顯示?創建/使用JPEG-2000格式的縮略圖時遇到問題
我的代碼來創建縮略圖是:
// This code 'downsamples' my very large digital pictures
// Thumbnail size
int pixelsWide = 72;
int pixelsHigh = 72;
CGContextRef myBitmapContext = NULL;
CGColorSpaceRef colorSpace;
void *bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
bitmapData = calloc(1, bitmapByteCount);
if(bitmapData == NULL) {
NSLog(@"Memory not allocated!");
} else {
myBitmapContext = CGBitmapContextCreate(bitmapData,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast);
if(myBitmapContext == NULL) {
free (bitmapData);
NSLog(@"myBitmapContext not created!");
}
}
CGColorSpaceRelease(colorSpace);
// This gets any zooming or rotating that I've done to the master image
CGAffineTransform imageTransformMatrix = [self generateImageTransformMatrixForRect: NSMakeRect(0.0, 0.0, (CGFloat) pixelsWide, (CGFloat) pixelsHigh)];
CGContextConcatCTM(myBitmapContext, imageTransformMatrix);
// imageRef is a CGImageRef to the master image to create the thumbnail of
double imgWidth = (double) CGImageGetWidth(imageRef);
double imgHeight = (double) CGImageGetHeight(imageRef);
NSRect dr = NSMakeRect(0, 0, imgWidth, imgHeight);
CGContextDrawImage(myBitmapContext, dr, imageRef);
// This code pulls the downsampled image back in to save to the database
thumbnailImageRef = CGBitmapContextCreateImage(myBitmapContext);
bitmapData = CGBitmapContextGetData(myBitmapContext);
CGContextRelease(myBitmapContext);
if(bitmapData) free(bitmapData);
NSDictionary *JPGopts = [NSDictionary dictionaryWithObjectsAndKeys: NSImageCompressionFactor, [NSNumber numberWithFloat: 0.0], nil];
NSBitmapImageRep *thumbnailBitmap = [[NSBitmapImageRep alloc] initWithCGImage: thumbnailImageRef];
NSData *thumbnailDataJPG = [thumbnailBitmap representationUsingType: NSJPEGFileType properties: JPGopts];
[thumbnailDataJPG writeToFile: @"/tmp/thumb.jpg" atomically: NO];
NSData *thumbnailDataPNG = [thumbnailBitmap representationUsingType: NSPNGFileType properties: nil];
[thumbnailDataPNG writeToFile: @"/tmp/thumb.png" atomically: NO];
NSData *thumbnailDataGIF = [thumbnailBitmap representationUsingType: NSGIFFileType properties: nil];
[thumbnailDataGIF writeToFile: @"/tmp/thumb.gif" atomically: NO];
NSData *thumbnailDataJPG2 = [thumbnailBitmap representationUsingType: NSJPEG2000FileType properties: nil];
[thumbnailDataJPG2 writeToFile: @"/tmp/thumb.jp2" atomically: NO];
[thumbnailBitmap release];
NSLog(@"The thumbnail sizes are %d for JPG, %d for PNG, %d for GIF, and %d for JPEG2000",
[thumbnailDataJPG length],
[thumbnailDataPNG length],
[thumbnailDataGIF length],
[thumbnailDataJPG2 length]);
// At this point I will store the selected NSData object to a BLOB in my database...
// I change the 1's to 0's and rebuild to try different formats
#if 1
CGImageSourceRef thumbSrc = CGImageSourceCreateWithData((CFDataRef) thumbnailDataJPG2, NULL);
#elif 1
CGImageSourceRef thumbSrc = CGImageSourceCreateWithData((CFDataRef) thumbnailDataGIF, NULL);
#elif 1
CGImageSourceRef thumbSrc = CGImageSourceCreateWithData((CFDataRef) thumbnailDataPNG, NULL);
#else
CGImageSourceRef thumbSrc = CGImageSourceCreateWithData((CFDataRef) thumbnailDataJPG, NULL);
#endif
thumbnailImageRef = CGImageSourceCreateImageAtIndex(thumbSrc, 0, NULL);
然後在我的drawRect
方法,我做的:。
CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];
if(thumbnailImageRef) {
imgWidth = (double) CGImageGetWidth(thumbnailImageRef);
imgHeight = (double) CGImageGetHeight(thumbnailImageRef);
// Make 4-pixel red border around thumbnail
CGContextSetRGBFillColor(myContext, 1, 0, 0, 1);
CGContextFillRect(myContext, CGRectMake(96, 96, imgWidth+8, imgHeight+8));
// Draw the thumbnail image
CGContextDrawImage(myContext, NSMakeRect(100, 100, imgWidth, imgHeight), thumbnailImageRef);
}
當我看着拇指*文件預覽看起來都很好(除JPG以外,因爲它有任何未填充區域的白色背景)。但是,如果我使用JPEG-2000,則在drawRect
中顯示的thumbnailImageRef
在圖像外部(在我放在它下面的紅色矩形中)之外有額外的黑色標記。它看起來非常適合PNG和GIF,除了白色背景之外,看起來還可以用於JPG。但是由於JPEG-2000是我真正想要使用的下一個最小對象的四分之一大小。
我無法弄清楚這個小黑點是從哪裏來的。有沒有人有什麼建議?
實施例的屏幕截圖: 圖像被顯示爲縮略圖(忽略紅色正方形)從
縮圖上述使用JPEG-2000作爲thumbnailSrc(在紅色正方形)
縮圖從頂部使用JPEG(在紅色方塊中)
從頂部使用GIF的縮略圖(在紅色方塊中)
我在這兩者之間切換的唯一更改是#if /#elif /#endif部分中的'1和'0。
我想使用JPEG-2000的大小的原因,但它看起來像GIF圖像呢。
謝謝!
請包含截圖/示例輸出圖像。 –
添加到帖子的圖像。第一個是縮略圖的視圖(忽略紅色方塊),下一個顯示縮略圖在紅色方塊中。這些都是'thumbnailJPG2'作爲'thumbSrc'。下一個是JPEG,而下一個是GIF。 – LavaSlider