1

I am working on a quicklook plugin for our custom document format on MacOS. We are storing a preview as jpg data right in the document. The document is a binary file and not a bundle. So far everything works fine for viewing thumbnails on quicklook by passing the jpg to quicklook with QLThumbnailRequestSetImageWithData.

However, trying to do the exact same for a quicklook preview using QLPreviewRequestSetDataRepresentation does not work. So I even tried to convert the data to an NSImage first and pass its tiff representation but to avail.

It seems it tries to create the preview (as can bee seen on the log) but then, without complaining just also creates the thumbnail and views just the thumbnail in the QuickLook Preview panel. See the log of one call to qlmanage to show a preivew of a test document:

$qlmanage -p Domino.abd
Testing Quick Look preview with files:
    Domino.abd
2018-03-05 12:17:09.415 qlmanage[7268:97108] Creating a preview for file:///Users/Shared/Test/Domino.abd
2018-03-05 12:17:09.419 qlmanage[7268:97108] Size {600, 845.25}
2018-03-05 12:17:09.431 qlmanage[7268:97108] key: Width, value: 600
2018-03-05 12:17:09.431 qlmanage[7268:97108] key: Height, value: 845
2018-03-05 12:17:09.431 qlmanage[7268:97108] key: kCGImageSourceTypeIdentifierHint, value: public.tff
2018-03-05 12:17:09.477 qlmanage[7268:97107] Creating a thumbnail for file:///Users/Shared/Test/Domino.abd

The relevant code in GeneratePreviewForURL looks like this:

OSStatus GeneratePreviewForURL(void *thisInterface, QLPreviewRequestRef preview, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options)
{

    NSLog(@"Creating a preview for %@", url);

    // Load the info header of our document
    CInfoHeader *infoHeader = [[CInfoHeader alloc] initWithUrl:url];
    if (![infoHeader load])
    {
        NSLog(@"Failed to load the Info Header");
        return noErr;
    }

    // Cancel the request if necessary
    if (QLPreviewRequestIsCancelled(preview))
        return noErr;

    // Get the thumbnail stored in the Worksheet Crafter document
    NSData *jpgData = [infoHeader imageData];
    if (!jpgData)
    {
        NSLog(@"No image data in the Info Header");
        return noErr;
    }

    // Convert the raw image to an NSImage since passing the raw data did not work even though it should have
    NSImage *image = [[NSImage alloc] initWithData:jpgData];
#if DEBUG
    NSLog(@"Size %@", NSStringFromSize([image size]));
#endif

    // Get the TIFF representation
    CFDataRef imageData = (__bridge CFDataRef)[image TIFFRepresentation];

    // Set up the hints for the preview
    NSDictionary *properties = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt:image.size.width],kQLPreviewPropertyWidthKey,
                                [NSNumber numberWithInt:image.size.height],kQLPreviewPropertyHeightKey,
                                @"public.tff", kCGImageSourceTypeIdentifierHint,
                                nil];
#if DEBUG
    for (id key in properties)
        NSLog(@"key: %@, value: %@", key, [properties objectForKey:key]);
#endif

    // Return the preview to Quick Look
    QLPreviewRequestSetDataRepresentation(preview,  imageData, kUTTypeImage, (__bridge CFDictionaryRef)properties);

    // Report success
    return noErr;
}

Just for completeness the relevant code that works for the thumbnails in GenerateThumbnailForURL:

OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thumbnail, CFURLRef url, CFStringRef contentTypeUTI, CFDictionaryRef options, CGSize maxSize)
{
    NSLog(@"Creating a thumbnail for %@", url);

    // Load the info header of our document
    CInfoHeader *infoHeader = [[CInfoHeader alloc] initWithUrl:url];
    if (![infoHeader load])
    {
        NSLog(@"Failed to load the Info Header");
        return noErr;
    }

    // Cancel the request if necessary
    if (QLThumbnailRequestIsCancelled(thumbnail))
        return noErr;

    // Get the thumbnail stored in our document
    NSData *jpgData = [infoHeader imageData];
    if (!jpgData)
    {
        NSLog(@"No image data in the Info Header");
        return noErr;
    }

    // Set the hint to be a jpeg image
    NSDictionary *properties = [NSDictionary dictionaryWithObject:@"public.jpeg" forKey:(__bridge NSString *)kCGImageSourceTypeIdentifierHint];

    // Return the thumbnail to Quick Look
    QLThumbnailRequestSetImageWithData(thumbnail, (__bridge CFDataRef)jpgData, (__bridge CFDictionaryRef)properties);

    // Report success
    return noErr;
}

0 Answers0