最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

objective c - NSImage is very slow with HEIC images - Stack Overflow

programmeradmin7浏览0评论

I have a command line program to convert images to JPEG which works but is very slow at converting some HEIC images from an iPhone 16. For example, a 3MB (5712x4284) HEIC image takes 1.4s to process, whereas converting the same image saved as a 100MB TIFF only takes 0.25s. Is there any way to speed this up?

(All the time is spent in drawInRect, actually compressing it to JPEG etc. only takes about 25ms.)

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#include <sys/xattr.h>
#include <sys/time.h>
#include <stdio.h>

long currentTimeMillis()
{
    struct timeval t;
    gettimeofday(&t, NULL);
    return t.tv_sec*1000L + t.tv_usec/1000;
}

void convertToJPEG(const char* inf, const char* outf)
{
    long t0 = currentTimeMillis();
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    NSString* str = [NSString stringWithUTF8String:inf];

    NSImage *image = [[NSImage alloc]initWithContentsOfFile:str];
    NSSize size = [image size];
    printf("+%ld origsize %g x %g\n", currentTimeMillis()-t0, size.width, size.height);
    size.width /= 2;
    size.height /= 2;

    NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]
              initWithBitmapDataPlanes:NULL
                            pixelsWide:size.width
                            pixelsHigh:size.height
                         bitsPerSample:8
                       samplesPerPixel:4
                              hasAlpha:YES
                              isPlanar:NO
                        colorSpaceName:NSCalibratedRGBColorSpace
                           bytesPerRow:0
                          bitsPerPixel:0];

    [NSGraphicsContext saveGraphicsState];
    [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:rep]];
    printf("+%ld setup\n", currentTimeMillis()-t0);

    // Draw scaled image into representation  **** THIS STEP IS SLOW ****
    [image drawInRect:NSMakeRect(0, 0, size.width, size.height) fromRect:NSZeroRect operation:NSCompositingOperationCopy fraction:1.0];
    
    printf("+%ld drawInRect\n", currentTimeMillis()-t0);
    [NSGraphicsContext restoreGraphicsState];

    // Compress representation to JPEG
    [rep setProperty:NSImageColorSyncProfileData withValue:nil];
    NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.5] forKey:NSImageCompressionFactor];
    NSData* data = [rep representationUsingType:NSBitmapImageFileTypeJPEG properties:imageProps];
    printf("+%ld compressed\n", currentTimeMillis()-t0);

    int length = [data length];
    void* bytes = malloc(length);
    [data getBytes:bytes length:length];
    
    FILE* out = fopen(outf, "w");
    fwrite(bytes, 1, length, out);
    fclose(out);
    free(bytes);

    [rep release];
    [image release];
    [pool release];
    printf("+%ld finished\n", currentTimeMillis()-t0);
}

int main(int argc, const char** argv)
{
    convertToJPEG(argv[1], "out.jpg");
}

Compile with gcc -o tojpeg tojpeg.mm -framework CoreServices -framework AppKit. (Apologies for the ugly mishmash of technologies, that's partly historical and partly a consequence of stripping it down to a SSCCE.)

发布评论

评论列表(0)

  1. 暂无评论