Сохранение предварительных просмотров и миниатюр в документе
Как один подход для обеспечения миниатюры и данных предварительного просмотра к Беглому взгляду, приложение может хранить те данные как часть данных документа. Генератор может тогда получить доступ к нему и возвратить его Беглому взгляду в вызове к QLThumbnailRequestSetImageWithData
или QLPreviewRequestSetDataRepresentation
. Этот подход разрешает быстрое время отклика для генератора, но за счет большего файла документа.
Чтобы проиллюстрировать, как Ваш генератор мог бы обеспечить предварительные просмотры и миниатюры с помощью этого подхода, следующие списки показывают модификации коду для приложения Эскиза, пишущего изображение миниатюр как часть данных документа. Перечисление 7-1 показывает, как Вы могли бы определить свойство NSDocument
разделите на подклассы для содержания данных изображения.
Проект Эскиза перечисления 7-1 в качестве примера: добавление свойства миниатюры
@interface SKTDrawDocument : NSDocument { |
@private |
NSMutableArray *_graphics; |
// ...other instance variables here... |
NSData *_thumbnail; |
} |
// ...existing methods here... |
- (NSData *)thumbnail; |
Реализуйте thumbnail
метод доступа возвратить изображение миниатюр. К NSDocument
метод, подготавливающий данные документа к выписыванию к файлу (dataOfType:error:
) добавляются строки кода в Перечислении 7-2, обозначенном «новыми» метками.
Проект Эскиза перечисления 7-2 в качестве примера: включая миниатюру с данными документа
static NSString *SKTThumbnailImageKey = @"SketchThumbnail"; // new |
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError { |
NSData *data,; |
NSArray *graphics = [self graphics]; |
NSPrintInfo *printInfo = [self printInfo]; |
NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; |
BOOL useTypeConformance = [workspace respondsToSelector:@selector(type:conformsToType:)]; |
if ((useTypeConformance && [workspace type:SKTDrawDocumentNewTypeName conformsToType:typeName]) |
|| [typeName isEqualToString:SKTDrawDocumentOldTypeName]) { |
NSData *tiffRep; // new |
NSMutableDictionary *properties = [NSMutableDictionary dictionary]; |
[properties setObject:[NSNumber numberWithInt:SKTDrawDocumentCurrentVersion] forKey:SKTDrawDocumentVersionKey]; |
[properties setObject:[SKTGraphic propertiesWithGraphics:graphics] forKey:SKTDrawDocumentGraphicsKey]; |
[properties setObject:[NSArchiver archivedDataWithRootObject:printInfo] forKey:SKTDrawDocumentPrintInfoKey]; |
tiffRep = [self TIFFDataWithGraphics:graphics error:outError]; // new |
[properties setObject:tiffRep forKey:SKTThumbnailImageKey]; // new |
data = [NSPropertyListSerialization dataFromPropertyList:properties |
format:NSPropertyListBinaryFormat_v1_0 |
errorDescription:NULL]; |
} else if ((useTypeConformance && [workspace type:(__bridge NSString *)kUTTypePDF conformsToType:typeName]) |
|| [typeName isEqualToString:NSPDFPboardType]) { |
data = [SKTRenderingView pdfDataWithGraphics:graphics]; |
} else { |
NSParameterAssert((useTypeConformance && [workspace type:(__bridge NSString *)kUTTypeTIFF conformsToType:typeName]) |
|| [typeName isEqualToString:NSTIFFPboardType]); |
data = [SKTRenderingView tiffDataWithGraphics:graphics error:outError]; |
} |
return data; |
} |
В соответствии NSDocument
метод для чтения данных документа въезжает задним ходом (readFromData:ofType:error:
) «распакуйте» миниатюру из словаря свойств документа:
_thumbnail = [properties objectForKey:SKTThumbnailImageKey]; |
Теперь реализация генератора для Эскиза является простым вопросом доступа к данным изображения миниатюр и передачи его к Беглому взгляду в вызове к QLThumbnailRequestSetImageWithData
, как показано в Перечислении 7-3. (Для предварительных просмотров соответствующая функция QLPreviewRequestSetDataRepresentation
.)
Перечисление 7-3 Возвращая сохраненное изображение миниатюр Беглому взгляду
OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize) |
{ |
@autoreleasepool { |
SKTDrawDocument* document = [[SKTDrawDocument alloc] init]; |
if (![document readFromURL:(__bridge NSURL *)url |
ofType:(__bridge NSString *)contentTypeUTI]) { |
return noErr; |
} |
if ([document respondsToSelector:@selector(thumbnail)]) { // runtime verification |
NSData *tiffData = [document thumbnail]; |
if (tiffData != nil) { |
NSDictionary *props = [NSDictionary dictionaryWithObject:@"public.tiff" forKey:(__bridge NSString *)kCGImageSourceTypeIdentifierHint]; |
QLThumbnailRequestSetImageWithData(thumbnail, (__bridge CFDataRef)tiffData, (__bridge CFDictionaryRef)props); |
return noErr; |
} |
} |
NSSize canvasSize = [document canvasSize]; |
CGContextRef cgContext = QLThumbnailRequestCreateContext(thumbnail, *(CGSize *)&canvasSize, false, NULL); |
if (cgContext) { |
NSGraphicsContext* context = [NSGraphicsContext graphicsContextWithGraphicsPort:(void *)cgContext flipped:YES]; |
if (context) { |
[document drawDocumentInContext:context]; |
} |
QLThumbnailRequestFlushContext(thumbnail, cgContext); |
CFRelease(cgContext); |
} |
} |
return noErr; |
} |
В вызове к QLThumbnailRequestSetImageWithData
, генератор указывает формат изображения к Беглому взгляду с kCGImageSourceTypeIdentifierHint
свойство. Обратите внимание на то, что этот пример проверяет, реализует ли класс объекта документа thumbnail
метод доступа (для исключения предыдущих версий приложения) и, если так, это проверяет, возвращаются ли данные миниатюры. Если это не, это составляет изображение миниатюр в предоставленном беглым взглядом графическом контексте.