簡體   English   中英

如何在ImageIO iOS框架中升級圖像?

[英]How do I upscale an image in ImageIO iOS framework?

我經歷了逐步發現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)

但僅適用於下采樣。

如果我的圖像是全高清即。 1920 x 1080,它被調整大小(保持縱橫比),使其適合320 px horizo​​ntaly,因為這是我設置為最大水平尺寸。

但是,如果我傳入一個16像素×9像素的圖像..一個非常小的圖像(顯然具有16:9的寬高比)。 此圖像未調整大小。

我想將它調整為320 x 180像素。

是否有一個選項組合/一個錯過的方法調用/任何會在imageIO框架中給我的東西?

簡短的回答是你不能使用ImageIO做到這一點。

ImageIO旨在逐步加載圖像(如在Web圖像中 ),構建快速 縮略圖最大尺寸將是原始圖像之一 ),並構建緩存圖像或非圖像組。 這是手冊

最簡單的方法是使用UIKit ,並使用范圍內的比例比(0 <ratio <1)

例如,從16x9圖像變為230x180將是:

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

還有其他方法,如NSHipster所描述的那些稍微復雜但可能值得一看,並進行一些性能測試以選擇哪一個更好的上采樣。 但這要由你來測試。

無論哪種方式,結果都會非常糟糕,因為上采樣仍在研究中並且是一項非常困難的任務。

關於這個主題有幾篇論文,但它們通常與對特定類型的對象進行上采樣有關,這允許算法做出一些必要的假設,例如: 幻覺面:TensorPatch超分辨率和耦合殘差補償

如果我選擇一種方法來實現這一點,質量是我的目標,我會選擇超分辨率的 OpenCV 算法

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

這是一個如何使用流行的圖像“ 莉娜 ”的演示文稿

所以,你可能需要重新考慮這個有多重要你的應用程序,也許找到一個解決辦法,因為會有沒有辦法,現在二者實現質量和接近實時的性能。 ;-)

快樂的編碼!

UpSampling Images,一些注釋:

(不幸的是,這將用Objective-C編寫,部分原因是由於ImageMagick本身的復雜性,它是用C代碼編寫的,就是這樣,沒有ObjC或Swift)

ImageMagick的

可能最好的圖像模塊庫之一是ImageMagick,這個庫由很多人構建,特別值得注意的是Nicolas Robidoux ,他目前是Phase One的高級研究科學家。 第一階段是:

Phase One是開放平台,高端中畫幅相機系統和解決方案的全球領導者。 我們的產品以其質量,靈活性和速度而聞名,使專業攝影師能夠以各種格式進行拍攝。

尼古拉斯擁有新墨西哥大學的應用數學博士學位,並在ImageMagick工作了一段時間。 以下是尼古拉斯關於對圖像進行上采樣的說法:

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

推薦的上采樣方法(放大)使用LanczosSharp EWA濾波器通過Sigmoidized色彩空間調整大小的結果是相當模糊的,如果有點模糊。 在簡答中討論的內置LanczosSharp效果很好,但我更喜歡使用“-filter Lanczos -define filter:blur = .9891028367558475”獲得的去模糊度略低的版本。

convert {input} -colorspace RGB + sigmoidal-contrast 7.5 \\ -filter Lanczos -define filter:blur = .9891028367558475 \\ -distort Resize 500%\\ -sigmoidal-contrast 7.5 -colorspace sRGB {output}

使用內置的LanczosSharp濾鏡可以獲得幾乎相同的結果,該濾鏡是通過“-filter LanczosSharp”替換“-filter Lanczos -define filter:blur = .9891028367558475”獲得的。

哇,這是一些很棒的東西,尼古拉斯告訴我們還有什么:

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

調整大小時,I(Nicolas Robidoux)通常會選擇張量(正交或2遍)Resize(-resize)運算符濾波器,或EWA(橢圓加權平均)Distort Resize(-distort Resize)運算符。 雖然用於張量和EWA操作的過濾器內核是使用相同的數學函數族構建的,但當與-resize一起使用時以及與-distort Resize一起使用時,它們會產生非常不同的結果。

如果您想為所有內容使用一個單獨的過濾器,而寧願避免顏色空間操作和花式參數等復雜問題,請使用LanczosSharp EWA(橢圓加權平均)濾波器。 它會產生稍微模糊的圖像,沒有鋸齒狀的說法和相當溫和的光暈。

這看起來是半復雜的,所以讓我們看看我們可以在IOS中實際上做得很容易,因為一些已經可用的工具保持最新並且是超級友好的IOS。

我們如何在IOS中做到這一點?嗯,如果你想嘗試一下,有一個ImageMagick POD,不幸的是它有點難以使用。 而且,還有Brad Larson的GPU Image,(感謝Brad !,偉大的圖書館)。 因此,為了時間的推移,我將堅持使用Brad的GPUImage處理庫,讓您快速了解“上采樣”以及您可以期待的內容。 我將使用Shapren和Lanczos過濾器,就像Nicholas建議的那樣,不幸的是,據我所知,看起來GPUImage沒有專門的“張量”或“LanczosSharp EWA”過濾器,如果我錯了,請隨時糾正我。 那么,說到這里,我們走了:

我將使用這個圖像,這是一個簡單的“書”圖標:

在此輸入圖像描述

將此圖像放在代碼中顯示以下內容,這是由XCode使用上面“書籍圖標”的矢量化PDF提取的未經修改的圖像,這里是結果:

沒有UPSAMPLING:

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

在此輸入圖像描述

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;

在此輸入圖像描述

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];

在此輸入圖像描述

因此,這可以讓您快速了解有關上采樣的內容,顯然,使用ImageMagick庫可能會產生更好的結果,也可能不會產生更好的結果,不幸的是,我沒有時間潛水,先讓ImageMagick庫啟動並運行,但是我在帖子中包含的內容可以幫助你找到某種解決方案,盡管這可能是一個半模糊的解決方案,但盡管如此,人類可以根據我們的計算技術和當前的解決方案將最佳解決方案放在一起數學。 也許有更多的信息比我在這里列出的更近,但是出於所有意圖和目的,我覺得我聯系的信息將為你提供最好的機會,讓你最快到達你想要最快的地方,除非您有時間編寫自己的圖像庫。

無論如何,如果您想嘗試在您的應用程序中實現Nicholas的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;

並且,你必須做舊的,“viewDidUnlaod”的東西:

-(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;

在此輸入圖像描述

RobidouxSharpFilter這是尼古拉斯的過濾器

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;

在此輸入圖像描述

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;

在此輸入圖像描述

我顯然可以繼續沿着這條路前進,但我現在要由你決定。 祝你好運,這里列出了你可以“輕松”使用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

來自kCGImageSourceThumbnailMaxPixelSize的文檔:

縮略圖的最大寬度和高度(以像素為單位)。 如果未指定此鍵,則縮略圖的寬度和高度不受限制,縮略圖可能與圖像本身一樣大

(強調我的)。

我認為這意味着縮略圖不能大於原始圖像。

為此,您可以執行以下操作:

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM