如何在ImageIO iOS框架中升级图像?

时间:2015-08-11 13:20:03

标签: ios swift

我经历了逐步发现iOS中表现最佳的图像大小调整解决方案的常规过程,最终我得到了ImageIO。

以下效果很好

if let currentImage = CGImageSourceCreateWithData(imageData, nil)

   //...some code that extracts the existing size, and based on my maximum expected horizontal size..calculates a new horizontal/vertical maximum size..

let options: CFDictionary = [kCGImageSourceThumbnailMaxPixelSize as NSString            : maximumImageWidthOrHeight,
                             kCGImageSourceCreateThumbnailFromImageAlways as NSString   : true]

CGImageSourceCreateThumbnailAtIndex(image, options)

但仅适用于下采样。<​​/ p>

如果我的图像是全高清即。 1920 x 1080,它被调整大小(保持纵横比),使其适合320 px horizo​​ntaly,因为这是我设置为最大水平尺寸。

然而,如果我传入一个16像素×9像素的图像..一个非常小的图像(显然具有16:9的宽高比)。此图片未调整大小。

我希望将其调整为320 x 180像素。

是否有选项组合/错过方法调用/任何可以在imageIO框架中为我提供的方法?

4 个答案:

答案 0 :(得分:11)

简短的回答是你不能使用 ImageIO 来做到这一点。

ImageIO 旨在逐步加载图片(如网络图片),构建快速 缩略图(< em> 最大尺寸将是原始图像 之一,并构建缓存或不是图像的组。 Here's the manual

最简单的方法是使用 UIKit ,并使用(0 <&lt; 1&lt; 1)范围内的比例比率。

  

例如,从 16x9 图片转到 230x180 将是:

 let image = UIImage(data: yourImageData!, scale: 0.050)!

还有其他方法,如NSHipster中所描述的那些稍微复杂但可能值得一看的方法,并进行一些性能测试以选择哪一个更好的上采样。但那要由你来测试。

无论哪种方式,结果都会非常糟糕,因为上采样 仍处于研究阶段,这是一项非常艰巨的任务。

  

关于这个主题有几篇论文,但它们通常是相关的   上采样特定类型的对象,这允许   算法做出一些必要的假设,例如:   Hallucinating Faces: TensorPatch Super-Resolution and Coupled Residue Compensation

     

如果我选择一种方法来实现这一目标并且质量是我的目标,那么我会选择OpenCV algorithms on superresolution

     

但是,它们是迭代算法,因此可能不适合您的性能需求。

     

Here's a demostration of how it works with the popular image "Lena"

所以,您可能需要重新考虑这对您的应用程序有多重要,并且可能找到一种解决方法,因为无法同时实现质量和接近实时性能现在 。的; - )

快乐编码!

答案 1 :(得分:7)

UpSampling图片,一些注意事项:

(不幸的是,这将用Objective-C编写,部分原因是由于ImageMagick本身的复杂性,它是用C代码编写的,那就是那个,那里有没有ObjC或Swift)

<强> ImageMagick的

可能最好的图像模块库之一是ImageMagick,这个库已经由很多人构建,特别值得注意的是 Nicolas Robidoux ,他目前担任高级研究科学家在第一阶段。第一阶段是:

  

Phase One是开放平台,高端媒体的全球领导者   格式相机系统和解决方案。我们的产品以其产品而闻名   质量,灵活性和速度使专业摄影师能够进行拍摄   各种格式。

Nicholas拥有新墨西哥大学的应用数学博士学位,并在ImageMagick工作了一段时间。以下是尼古拉斯关于对图像进行上采样的说法:

http://www.imagemagick.org/Usage/filter/nicolas/#upsampling

  

推荐的上采样方法(放大)   使用调整大小的结果   通过Sigmoidized色彩空间的LanczosSharp EWA滤波器   如果有点模糊,相当没有人工制品。内置的LanczosSharp,   在简答中讨论,效果很好,但我更喜欢使用   使用&#34; -filter Lanczos -define获得的去模糊效果稍差   滤波器:模糊= 0.9891028367558475&#34;

     

转换{input} -colorspace RGB + Sigmoidal-contrast 7.5 \             -filter Lanczos -define filter:blur = .9891028367558475 \             -distort调整大小500%             -sigmoidal-contrast 7.5 -colorspace sRGB {output}

     

使用内置的LanczosSharp可以得到几乎相同的结果   过滤器,通过替换&#34; -filter Lanczos -define获得   滤波器:模糊= 0.9891028367558475&#34; by&#34; -filter LanczosSharp&#34;。

哇,这是一些很棒的东西,尼古拉斯告诉我们还有什么:

http://www.imagemagick.org/Usage/filter/nicolas/

  

在调整大小时,我(Nicolas Robidoux)通常会坚持要么张紧   (正交或2遍)调整大小(-resize)运算符过滤器或EWA   (椭圆加权平均)扭曲调整大小(-distort Resize)   运营商。虽然滤波器内核与张量和EWA一起使用   使用相同的数学族建立操作   函数,与-resize一起使用时,它们会产生非常不同的结果   与-distort Resize一起使用时。

     

如果你想为一切使用一个单一的过滤器而宁愿   避免色彩空间操纵和幻想等复杂问题   参数,使用LanczosSharp EWA(椭圆加权平均)   过滤。它产生的图像稍微模糊,没有锯齿   谈论和相当温和的光环。

这听起来有点复杂,所以让我们看看我们可以在IOS中轻松地做一些事情,因为一些已经可用的工具可以保持最新并且对IOS非常友好。

我们如何在IOS中执行此操作?嗯,如果您想尝试一下ImageMagick POD,不幸的是,它有点难以使用。此外,还有Brad Larson的GPU Image(感谢Brad!,伟大的图书馆)。因此,为了时间的推移,我将坚持使用Brad的GPUImage处理库,让您快速了解&#34; upampling&#34;你能期待什么我将使用Shapren和Lanczos过滤器,正如尼古拉斯建议的那样,不幸的是,据我所知,看起来GPUImage没有&#34;张量&#34;或者&#34; LanczosSharp EWA&#34;具体过滤,如果我错了,请随时纠正我。那么,说到这里,我们走了:

我将使用这张图片,这是一本简单的书#34;图标:

enter image description here

将此图像放置在代码中显示以下内容,这是未经过修改的图像,由XCode使用&#34;书籍图标&#34;的矢量化PDF提取。上面,结果如下:

没有UPSAMPLING:

UIImage *inputImage = [UIImage imageNamed:@"book"];
cell.imageView.image = inputImage;

enter image description here

LANCZOS UPSAMPLING:

UIImage *inputImage = [UIImage imageNamed:@"book"];
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage];
GPUImageLanczosResamplingFilter *stillImageFilter = [[GPUImageLanczosResamplingFilter alloc] init];
[stillImageSource addTarget:stillImageFilter];
[stillImageFilter useNextFrameForImageCapture];
[stillImageSource processImage];
[stillImageSource forceProcessingAtSizeRespectingAspectRatio:CGSizeMake(200, 200)];
UIImage *currentFilteredVideoFrame = [stillImageFilter imageFromCurrentFramebuffer];
cell.imageView.image = currentFilteredVideoFrame;

enter image description here

SHARPEN UPSAMPLING:

UIImage *inputImage = [UIImage imageNamed:@"book"];
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:inputImage];
GPUImageSharpenFilter *stillImageFilter = [[GPUImageSharpenFilter alloc] init];
[stillImageSource addTarget:stillImageFilter];
[stillImageFilter useNextFrameForImageCapture];
[stillImageSource processImage];
UIImage *currentFilteredVideoFrame = [stillImageFilter imageFromCurrentFramebuffer];

enter image description here

因此,这可以让您快速了解有关上采样的内容,显然,使用ImageMagick库可能会产生或不会产生更好的结果,不幸的是,我没有时间先潜水让ImageMagick库启动并运行,但是我在帖子中包含的内容可以帮助你找到某种解决方案,尽管这可能是一个半模糊的解决方案,但仍然是最好的解决方案鉴于我们的计算技术和当前的数学,人类可以将它们组合在一起。也许有更多的信息是我在这里列出的最新信息,但出于所有意图和目的,我觉得我所关联的信息会给你最好的机会到你想要最快的地方,除非你有时间写自己的图像库。

无论如何,如果您想尝试实施Nicholas&#39;在您的应用中使用ImageMagick技术,可以通过安装以下POD来试一试:

pod 'ImageMagick', '6.8.8-9'

对于Brad Larson的GPUImage,POD是:

pod 'GPUImage'

如果您对如何使IOS ImageMagick库工作有疑问:

http://blog.splitwise.com/2012/12/18/imagemagick-for-ios-armv7-and-armv7s/

https://github.com/marforic/imagemagick_lib_iphone

http://www.cloudgoessocial.net/2011/03/21/im-xcode4-ios4-3/

如果你想看看Brad Larson在一起的内容,请点击这里的github回购:

https://github.com/BradLarson/GPUImage

为了扩展我的答案,我决定首先跳到ImageMagick头,这里是结果,这些结果基于PNG文件,而不是矢量化PDF文件:

首先,请确保导入此标头:

#import <wand/MagickWand.h>

这是你的财产声明

@property (nonatomic) MagickWand *wand;

而且,你必须做旧的,&#34; viewDidUnlaod&#34;充塞:

-(void)viewDidUnload
{
    if (self.wand)
        self.wand = DestroyMagickWand(self.wand);
    MagickWandTerminus();
}

<强> Lanczos2SharpFilter

MagickWandGenesis();
self.wand = NewMagickWand();
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"book" ofType:@"png"];
MagickReadImage(self.wand, [filePath cStringUsingEncoding:NSASCIIStringEncoding]);
MagickResampleImage(self.wand,100,100,Lanczos2SharpFilter, 2),
MagickWriteImage(self.wand, [filePath cStringUsingEncoding:NSASCIIStringEncoding]);
UIImage *imgObj = [UIImage imageWithContentsOfFile:filePath];
cell.imageView.image = imgObj;

enter image description here

RobidouxSharpFilter这是尼古拉斯&#39;过滤

MagickWandGenesis();
self.wand = NewMagickWand();
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"book" ofType:@"png"];
MagickReadImage(self.wand, [filePath cStringUsingEncoding:NSASCIIStringEncoding]);
MagickResampleImage(self.wand,75,75,RobidouxSharpFilter, 1),
MagickWriteImage(self.wand, [filePath cStringUsingEncoding:NSASCIIStringEncoding]);
UIImage *imgObj = [UIImage imageWithContentsOfFile:filePath];
cell.imageView.image = imgObj;

enter image description here

<强> LanczosSharpFilter

MagickWandGenesis();
self.wand = NewMagickWand();
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"book" ofType:@"png"];
MagickReadImage(self.wand, [filePath cStringUsingEncoding:NSASCIIStringEncoding]);
MagickResampleImage(self.wand,75,75,LanczosSharpFilter, 1),
MagickWriteImage(self.wand, [filePath cStringUsingEncoding:NSASCIIStringEncoding]);
UIImage *imgObj = [UIImage imageWithContentsOfFile:filePath];
cell.imageView.image = imgObj;

enter image description here

我显然可以继续沿着这条路走下去,但我现在要由你决定。祝你好运,这里列出了你可以轻松获得的所有过滤器#34; EASILY&#34;与ImageMagick一起使用;

  

UndefinedFilter,PointFilter,BoxFilter,TriangleFilter,
  HermiteFilter,HanningFilter,HammingFilter,BlackmanFilter,
  GaussianFilter,QuadraticFilter,CubicFilter,CatromFilter,
  MitchellFilter,JincFilter,SincFilter,SincFastFilter,
  KaiserFilter,WelshFilter,ParzenFilter,BohmanFilter,
  BartlettFilter,LagrangeFilter,LanczosFilter,
  LanczosSharpFilter,Lanczos2Filter,Lanczos2SharpFilter,
  RobidouxFilter,RobidouxSharpFilter,CosineFilter,SplineFilter,   LanczosRadiusFilter,SentinelFilter

答案 2 :(得分:1)

来自.sweet-alert input { display: initial; width: auto; height: auto; margin: auto; } 的文档:

  

缩略图的最大宽度和高度(以像素为单位)。如果未指定此键,则缩略图的宽度和高度不受限制,缩略图可能与图像本身一样大

(强调我的)。

我认为这意味着缩略图不能大于原始图像。

答案 3 :(得分:0)

要实现此目的,您可以执行以下操作:

let provider: CGDataProviderRef = CGDataProviderCreateWithCFData(imageData)
let currentImage: CGImageRef = CGImageCreate(
   320, // width
   180, // height
   8, // bitsPerComponent
   32, // bitsPerPixel
   2560, // bytesPerRow
   CGColorSpaceCreateDeviceRGB(), //colorSpace
   kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, // bitmapInfo (direct memory copy options)
   provider, //image data
   nil, // decode
   true, // shouldInterpolate
   kCGRenderingIntentDefault // intent
   )
//Now you can use currentImage or create a UIImage from it depending on your needs.
let upScaled: UIImage = UIImage.imageWithCGImage(currentImage)
//Might need to release currentImage
//CGImageRelease(currentImage)