简体   繁体   English

如何在Cocoa Mac应用程序中合并大型JPEG

[英]How to combine large JPEG's in Cocoa Mac application

In our Mac application built in Cocoa, we would like to combine 5 large JPEG images into one JPEG. 在可可内置的Mac应用程序中,我们希望将5个大JPEG图像合并为一个JPEG。 We have the following images: 我们有以下图像:

  • 1.jpeg 50000px wide X 5000px high 1.jpeg 50000px宽X 5000px高
  • 2.jpeg 50000px wide X 5000px high 2.jpeg 50000px宽X 5000px高
  • 3.jpeg 50000px wide X 5000px high 3.jpeg 50000px宽X 5000px高
  • 4.jpeg 50000px wide X 5000px high 4.jpeg 50000px宽X 5000px高
  • 5.jpeg 50000px wide X 5000px high 5.jpeg 50000px宽X 5000px高

We would like to combine these images one above the other to form an output jpeg: 我们想将这些图像一个接一个地组合以形成输出jpeg:

50000px wide X 25000px high

The problem is that the resulting JPEG is very large and this results in memory issues when we use the following approach to make output JPEG. 问题是,当我们使用以下方法制作输出JPEG时,生成的JPEG很大,这会导致内存问题。

  NSRect imageRect = NSMakeRect(0.0, 0.0, 50000, 25000);

  NSBitmapImageRep *savedImageBitmapRep = [[NSBitmapImageRep alloc]
      initWithBitmapDataPlanes:nil
                    pixelsWide:imageRect.size.width
                    pixelsHigh:imageRect.size.height
                 bitsPerSample:8
               samplesPerPixel:4
                      hasAlpha:YES
                      isPlanar:NO
                colorSpaceName:NSCalibratedRGBColorSpace
                  bitmapFormat:0
                   bytesPerRow:(4 * imageRect.size.width)
                  bitsPerPixel:32];

  [NSGraphicsContext saveGraphicsState];
  [NSGraphicsContext
      setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:
                                               savedImageBitmapRep]];

  // Read 1.jpeg, 2.jpeg, 3.jpeg, 4.jpeg, 5.jpeg as NSImage 
  // and draw them on the current context in their respective location

  [NSGraphicsContext restoreGraphicsState];

  NSMutableData *imageData = [NSMutableData data];
  CGImageDestinationRef imageDest = CGImageDestinationCreateWithData(
        (__bridge CFMutableDataRef)imageData, kUTTypeJPEG, 1, NULL);

  CGImageDestinationAddImage(imageDest, [savedImageBitmapRep CGImage],
                             (__bridge CFDictionaryRef)properties);
  CGImageDestinationFinalize(imageDest);
  if (imageDest != NULL) {
    CFRelease(imageDest);
  }
  //write imageData to a JPEG file

How can we achieve our objective without facing memory issues? 我们如何在不面对内存问题的情况下实现目标?

"Memory issues" is vague but I assume you simply mean that you want to avoid the 4.5+ GBs of memory required to hold 50,000 x 25,000 pixels. “内存问题”含糊不清,但我想您只是想避免要保留50,000 x 25,000像素所需的4.5+ GB内存。

The only way to avoid that is to drop down to a lower level API which lets you encode each MCU row (each 8 or 16 rows of pixels) separately at a time. 避免这种情况的唯一方法是降低到较低级别的API,该API允许您一次对每个MCU行(每个8或16行像素)分别进行编码。 libjpeg supports this, for example. 例如,libjpeg支持此功能。 You would load and render the minimum required data to produce such a row with whatever minimum memory constraints you have in mind, and then pass that row off to the encoder, before moving to the next row. 您将加载并呈现所需的最少数据,以在考虑任何最小内存限制的情况下生成这样的行,然后将该行传递给编码器,然后再移至下一行。

You can resize them to be smaller for displaying. 您可以将它们调整为较小的尺寸以进行显示。 but only when saving/storing you can directly store all the sizes 但只有在保存/存储时,您才能直接存储所有尺寸

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM