Я пытаюсь написать прототип, чтобы доказать, что преобразование RAW из одного формата в другое возможно. Мне нужно преобразовать необработанный файл Nikon с форматом .NEF в формат .CR2 от Canon. С помощью различных сообщений я создаю исходное изображение BitmapImageRep представления TIFF изображения и использую его для записи выходного файла с расширением .CR2.NSImage + NSBitmapImageRep = Преобразование файла изображения RAW из одного формата в другой
Это действительно работает, но для меня проблема только в том, что входной файл имеет 21,5 МБ, но выход am из 144,4 МБ. При использовании NSTIFFCompressionPackBits
дает мне 142.1 МБ.
Я хочу понять, что происходит, я попробовал различные сжатые копии, но без успеха.
Пожалуйста, помогите мне понять это. Это исходный код:
@interface NSImage(RawConversion)
- (void) saveAsCR2WithName:(NSString*) fileName;
@end
@implementation NSImage(RawConversion)
- (void) saveAsCR2WithName:(NSString*) fileName
{
// Cache the reduced image
NSData *imageData = [self TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
// http://www.cocoabuilder.com/archive/cocoa/151789-nsbitmapimagerep-compressed-tiff-large-files.html
NSDictionary *imageProps = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:NSTIFFCompressionJPEG],NSImageCompressionMethod,
[NSNumber numberWithFloat: 1.0], NSImageCompressionFactor,
nil];
imageData = [imageRep representationUsingType:NSTIFFFileType properties:imageProps];
[imageData writeToFile:fileName atomically:NO];
}
@end
Как я мог бы получить выходной файл, который находится в формате CR2, но почти по размеру входного файла с небольшим изменением, как требуется для файла CR2?
Edit 1: Done изменение, основанное на предложении Питера использования CGImageDestinationAddImageFromSource
метода, но до сих пор я получаю тот же результат. Размер исходного файла NEF источника 21,5 МБ, но размер файла назначения после преобразования 144,4 МБ.
Пожалуйста, ознакомьтесь код:
-(void)saveAsCR2WithCGImageMethodUsingName:(NSString*)inDestinationfileName withSourceFile:(NSString*)inSourceFileName
{
CGImageSourceRef sourceFile = MyCreateCGImageSourceRefFromFile(inSourceFileName);
CGImageDestinationRef destinationFile = createCGImageDestinationRefFromFile(inDestinationfileName);
CGImageDestinationAddImageFromSource(destinationFile, sourceFile, 0, NULL);
//https://developer.apple.com/library/mac/#documentation/graphicsimaging/Conceptual/ImageIOGuide/ikpg_dest/ikpg_dest.html
CGImageDestinationFinalize(destinationFile);
}
CGImageSourceRef MyCreateCGImageSourceRefFromFile (NSString* path)
{
// Get the URL for the pathname passed to the function.
NSURL *url = [NSURL fileURLWithPath:path];
CGImageSourceRef myImageSource;
CFDictionaryRef myOptions = NULL;
CFStringRef myKeys[2];
CFTypeRef myValues[2];
// Set up options if you want them. The options here are for
// caching the image in a decoded form and for using floating-point
// values if the image format supports them.
myKeys[0] = kCGImageSourceShouldCache;
myValues[0] = (CFTypeRef)kCFBooleanTrue;
myKeys[1] = kCGImageSourceShouldAllowFloat;
myValues[1] = (CFTypeRef)kCFBooleanTrue;
// Create the dictionary
myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
(const void **) myValues, 2,
&kCFTypeDictionaryKeyCallBacks,
& kCFTypeDictionaryValueCallBacks);
// Create an image source from the URL.
myImageSource = CGImageSourceCreateWithURL((CFURLRef)url, myOptions);
CFRelease(myOptions);
// Make sure the image source exists before continuing
if (myImageSource == NULL){
fprintf(stderr, "Image source is NULL.");
return NULL;
}
return myImageSource;
}
CGImageDestinationRef createCGImageDestinationRefFromFile (NSString *path)
{
NSURL *url = [NSURL fileURLWithPath:path];
CGImageDestinationRef myImageDestination;
//https://developer.apple.com/library/mac/#documentation/graphicsimaging/Conceptual/ImageIOGuide/ikpg_dest/ikpg_dest.html
float compression = 1.0; // Lossless compression if available.
int orientation = 4; // Origin is at bottom, left.
CFStringRef myKeys[3];
CFTypeRef myValues[3];
CFDictionaryRef myOptions = NULL;
myKeys[0] = kCGImagePropertyOrientation;
myValues[0] = CFNumberCreate(NULL, kCFNumberIntType, &orientation);
myKeys[1] = kCGImagePropertyHasAlpha;
myValues[1] = kCFBooleanTrue;
myKeys[2] = kCGImageDestinationLossyCompressionQuality;
myValues[2] = CFNumberCreate(NULL, kCFNumberFloatType, &compression);
myOptions = CFDictionaryCreate(NULL, (const void **)myKeys, (const void **)myValues, 3,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
//https://developer.apple.com/library/mac/#documentation/graphicsimaging/Conceptual/ImageIOGuide/imageio_basics/ikpg_basics.html#//apple_ref/doc/uid/TP40005462-CH216-SW3
CFStringRef destFileType = CFSTR("public.tiff");
// CFStringRef destFileType = kUTTypeJPEG;
CFArrayRef types = CGImageDestinationCopyTypeIdentifiers(); CFShow(types);
myImageDestination = CGImageDestinationCreateWithURL((CFURLRef)url, destFileType, 1, myOptions);
return myImageDestination;
}
Edit 2: Используется второй подход, рассказанную @Peter. Это дает интересный результат. Это то же самое, что и переименование файла в finder, например, example_image.NEF, на example_image.CR2. Удивительно, что происходит при преобразовании как программно, так и в finder, исходный файл, который составляет 21,5 МБ, окажется равным 59 КБ. Это без какого-либо сжатия, установленного в коде. Пожалуйста, смотрите код и предложить:
-(void)convertNEFWithTiffIntermediate:(NSString*)inNEFFile toCR2:(NSString*)inCR2File
{
NSData *fileData = [[NSData alloc] initWithContentsOfFile:inNEFFile];
if (fileData)
{
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:fileData];
// [imageRep setCompression:NSTIFFCompressionNone
// factor:1.0];
NSDictionary *imageProps = nil;
NSData *destinationImageData = [imageRep representationUsingType:NSTIFFFileType properties:imageProps];
[destinationImageData writeToFile:inCR2File atomically:NO];
}
}
Почему вы отметили это как [какао-touch], если используете NSImage и NSBitmapImageRep? –
Извините, спасибо за исправление. Я - разработчик iOS, и я использую его таким образом. Попробуй использовать оба этих метода. –
Переименование файла в Finder меняет свой размер на 59 K? Это не так. –