2011-01-17 6 views
36

小さいスペースに大きな画像を表示するアプリケーションがあります。 イメージはかなり大きいですが、100x100ピクセルのフレームでのみ表示しています。 私のアプリは、使用している画像のサイズがゆっくりと応答しています。iphoneのobjective-cでプログラムで画像のサイズを変更するには

Objective-Cを使用してプログラムでイメージのサイズを変更するにはどうすればよいですか?

+1

がhttp://stackoverflow.com/questions/2658738/the-simplest-way-to-を参照してください。このように、これを呼ばれますresize-an-uiimage – Costique

+0

私は、ピクセルを歩き、4ピクセルを1つに合計することによって、イメージを2倍にスケールダウンするコードを書きました。それは非常にうまくいっています(システムのスケーリングを使うよりも画質が良い)が、おそらく50行のコードであり、本当にかわいらしいものではありませんでした。 (そして、とにかくイメージを拡大縮小する必要はないことがわかりました) –

+0

ここに私のアルゴリズムが見つかるスレッドがあります:http:// stackoverflow。com/questions/6052188/high-quality-scaling-of-uiimage –

答えて

87

次のコードを見つけてください。

- (UIImage *)imageWithImage:(UIImage *)image convertToSize:(CGSize)size { 
    UIGraphicsBeginImageContext(size); 
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 
    UIImage *destImage = UIGraphicsGetImageFromCurrentImageContext();  
    UIGraphicsEndImageContext(); 
    return destImage; 
} 
+2

これはこれまではiOS5では機能していました。 0.1これはメモリリークを引き起こしています。これを達成するための他の方法は? http://stackoverflow.com/questions/8236837/memory-leak-drawinrect-on-ios5-0-1 – David

+0

これはまだiOS 6.xの問題ですか? – Paaske

+0

はい、それでもメモリリークが発生します。 –

0

コードが後方互換性のために、iOSの4に完全に罰金走ったので、私は、OSのバージョンと古いコードは動作します5.0の下に何のためのチェックを追加しました。

- (UIImage *)resizedImage:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)quality { 
    BOOL drawTransposed; 
    CGAffineTransform transform = CGAffineTransformIdentity; 

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) { 
     // Apprently in iOS 5 the image is already correctly rotated, so we don't need to rotate it manually 
     drawTransposed = NO; 
    } else {  
     switch (self.imageOrientation) { 
      case UIImageOrientationLeft: 
      case UIImageOrientationLeftMirrored: 
      case UIImageOrientationRight: 
      case UIImageOrientationRightMirrored: 
       drawTransposed = YES; 
       break; 

      default: 
       drawTransposed = NO; 
     } 

     transform = [self transformForOrientation:newSize]; 
    } 

    return [self resizedImage:newSize 
        transform:transform 
       drawTransposed:drawTransposed 
     interpolationQuality:quality]; 
} 
+2

コードが停止せずに呼び出されるようです。 – Binarian

4

私が好きな方法はCGImageSourceCreateThumbnailAtIndex(ImageIOフレームワーク内)です。名前は少し誤解を招く。

最近の私のアプリのコードの抜粋です。

CGFloat maxw = // whatever; 
CGFloat maxh = // whatever; 

CGImageSourceRef src = NULL; 
if ([imageSource isKindOfClass:[NSURL class]]) 
    src = CGImageSourceCreateWithURL((__bridge CFURLRef)imageSource, nil); 
else if ([imageSource isKindOfClass:[NSData class]]) 
    src = CGImageSourceCreateWithData((__bridge CFDataRef)imageSource, nil); 

// if at double resolution, double the thumbnail size and use double-resolution image 
CGFloat scale = 1; 
if ([[UIScreen mainScreen] scale] > 1.0) { 
    scale = 2; 
    maxw *= 2; 
    maxh *= 2; 
} 

// load the image at the desired size 
NSDictionary* d = @{ 
        (id)kCGImageSourceShouldAllowFloat: (id)kCFBooleanTrue, 
        (id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue, 
        (id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue, 
        (id)kCGImageSourceThumbnailMaxPixelSize: @((int)(maxw > maxh ? maxw : maxh)) 
        }; 
CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (__bridge CFDictionaryRef)d); 
if (NULL != src) 
    CFRelease(src); 
UIImage* im = [UIImage imageWithCGImage:imref scale:scale orientation:UIImageOrientationUp]; 
if (NULL != imref) 
    CFRelease(imref); 
0

これは使用できます。

[m_Image.layer setMinificationFilter:kCAFilterTrilinear];

+0

これはUIImageViewではなくUIImageViewに使用されます – vinceville

2

あなたは、異なるサイズの画像を使用して、それはあなたのアプリケーションのパフォーマンスが低下しますたびにリサイズされている場合。解決策は、画像ビューの代わりにボタンを使用するだけで、サイズを変更しません。自動的にサイズを変更するボタンの画像を設定するだけで、素晴らしいパフォーマンスが得られます。

セルに設定している間に画像のサイズを変更していましたが、アプリが遅くなってしまったので、画像ビューの代わりにButtonを使用しました。

5

このコードは画像のサイズを変更するためのものではありません。 画像の幅と高さをCGSizeに設定する必要があります。画像が伸びず、中央に配置されます。

- (UIImage *)imageWithImage:(UIImage *)image scaledToFillSize:(CGSize)size 
{ 
    CGFloat scale = MAX(size.width/image.size.width, size.height/image.size.height); 
    CGFloat width = image.size.width * scale; 
    CGFloat height = image.size.height * scale; 
    CGRect imageRect = CGRectMake((size.width - width)/2.0f, 
            (size.height - height)/2.0f, 
            width, 
            height); 

    UIGraphicsBeginImageContextWithOptions(size, NO, 0); 
    [image drawInRect:imageRect]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return newImage; 
} 
+0

これは私にとって完璧に動作します。 –

+0

コーディングをお楽しみください@NishadArora :) –

1
-(UIImage *)scaleImage:(UIImage *)image toSize:.  (CGSize)targetSize 
    { 
//If scaleFactor is not touched, no scaling will occur 
    CGFloat scaleFactor = 1.0; 

//Deciding which factor to use to scale the image (factor = targetSize/imageSize) 
if (image.size.width > targetSize.width || 
    image.size.height > targetSize.height || image.size.width == image.size.height) 
    if (!((scaleFactor = (targetSize.width/
    image.size.width)) > (targetSize.height/
     image.size.height))) //scale to fit width, or 
     scaleFactor = targetSize.height/image.size.height; // scale to fit heigth. 
0

このスレッドは古いですが、それはこの問題を解決しようとすると、私はプルアップするものです。一旦画像が拡大縮小されると、私は自動レイアウトをオフにしたにもかかわらず、コンテナにうまく表示されませんでした。私がテーブル行に表示するためにこれを解決する最も簡単な方法は、固定サイズの白い背景に画像をペイントすることでした。

ヘルパー機能

+(UIImage*)scaleMaintainAspectRatio:(UIImage*)sourceImage :(float)i_width :(float)i_height 
{ 
float newHeight = 0.0; 
float newWidth = 0.0; 

float oldWidth = sourceImage.size.width; 
float widthScaleFactor = i_width/oldWidth; 

float oldHeight = sourceImage.size.height; 
float heightScaleFactor = i_height/oldHeight; 
if (heightScaleFactor > widthScaleFactor) { 
    newHeight = oldHeight * widthScaleFactor; 
    newWidth = sourceImage.size.width * widthScaleFactor; 
} else { 
    newHeight = sourceImage.size.height * heightScaleFactor; 
    newWidth = oldWidth * heightScaleFactor; 
} 

// return image in white rect 
float cxPad = i_width - newWidth; 
float cyPad = i_height - newHeight; 
if (cyPad > 0) { 
    cyPad = cyPad/2.0; 
} 
if (cxPad > 0) { 
    cxPad = cxPad/2.0; 
} 

CGSize size = CGSizeMake(i_width, i_height); 
UIGraphicsBeginImageContextWithOptions(CGSizeMake(size.width, size.height), YES, 0.0); 
[[UIColor whiteColor] setFill]; 
UIRectFill(CGRectMake(0, 0, size.width, size.height)); 
[sourceImage drawInRect:CGRectMake((int)cxPad, (int)cyPad, newWidth, newHeight)]; 
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
return newImage; 

// will return scaled image at actual size, not in white rect 
// UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight)); 
// [sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)]; 
// UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 
// UIGraphicsEndImageContext(); 
// return newImage; 
} 

私は私のテーブルビューcellForRowAtIndexPathから

PFFile *childsPicture = [object objectForKey:@"picture"]; 
[childsPicture getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) { 
    if (!error) { 
     UIImage *largePicture = [UIImage imageWithData:imageData]; 
     UIImage *scaledPicture = [Utility scaleMaintainAspectRatio:largePicture :70.0 :70.0 ]; 
     PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100]; 
     thumbnailImageView.image = scaledPicture; 
     [self.tableView reloadData]; 
    } 
}]; 
関連する問題