简体   繁体   English

如何在iphone的objective-c中以编程方式调整图像大小

[英]How to resize the image programmatically in objective-c in iphone

I have an application where I am displaying large images in a small space.我有一个应用程序,我在一个小空间中显示大图像。 The images are quite large, but I am only displaying them in 100x100 pixel frames.图像非常大,但我只在 100x100 像素帧中显示它们。 My app is responding slowly because of the size fo the images I am using.由于我使用的图像的大小,我的应用程序响应缓慢。

To improve performance, how can I resize the images programmatically using Objective-C?为了提高性能,如何使用 Objective-C 以编程方式调整图像大小?

Please find the following code.请找到以下代码。

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

This code is for just change image scale not for resizing.此代码仅用于更改图像比例,而不用于调整大小。 You have to set CGSize as your image width and hight so the image will not stretch and it arrange at the middle.您必须将 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;
}

My favorite way to do this is with CGImageSourceCreateThumbnailAtIndex (in the ImageIO framework).我最喜欢的方法是使用CGImageSourceCreateThumbnailAtIndex (在 ImageIO 框架中)。 The name is a bit misleading.这个名字有点误导。

Here's an excerpt of some code from a recent app of mine.这是我最近的一个应用程序的一些代码的摘录。

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

If you are using a image on different sizes and resizing each time it will degrade your app performance.如果您使用不同大小的图像并每次都调整大小,则会降低您的应用程序性能。 Solution is don't resize them just use button in place of imageview.解决方案是不要调整它们的大小,只需使用按钮代替 imageview。 and just set the image on button it will resize automatically and you will get great performance.只需在按钮上设置图像,它就会自动调整大小,您将获得出色的性能。

I was also resizing images while setting it on cell but my app got slow So I used Button in place of imageview (not resizing images programatically button is doing this job) and it is working perfectly fine.我也在单元格上设置图像时调整图像大小,但我的应用程序变慢了所以我使用 Button 代替 imageview(不是以编程方式调整图像大小按钮正在完成这项工作)并且它工作得非常好。

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

Since the code ran perfectly fine in iOS 4, for backwards compatibility I added a check for OS version and for anything below 5.0 the old code would work.由于代码在 iOS 4 中运行得非常好,为了向后兼容,我添加了对操作系统版本和低于 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];
}

你可以用这个。

[m_Image.layer setMinificationFilter:kCAFilterTrilinear];

This thread is old, but it is what I pulled up when trying to solve this problem.这个线程很旧,但它是我在尝试解决这个问题时提出的。 Once the image is scaled it was not displaying well in my container even though I turned auto layout off.缩放图像后,即使我关闭了自动布局,它也无法在我的容器中很好地显示。 The easiest way for me to solve this for display in a table row, was to paint the image on a white background that had a fixed size.解决此问题以在表格行中显示的最简单方法是在具有固定大小的白色背景上绘制图像。

Helper function辅助功能

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

I called this like this from my table view cellForRowAtIndexPath我从我的表格视图 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];
    }
}];

Hello from the end of 2018. Solved with next solution (you need only last line, first & second are just for explanation): 2018 年底你好。解决了下一个解决方案(你只需要最后一行,第一行和第二行只是为了解释):

NSURL *url = [NSURL URLWithString:response.json[0][@"photo_50"]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data scale:customScale];

'customScale' is scale which you want (>1 if image must be smaller, <1 if image must be bigger). 'customScale' 是你想要的比例(>1 如果图像必须更小,<1 如果图像必须更大)。

This c method will resize your image with cornerRadius "Without effecting image's quality" :此 c 方法将使用cornerRadius“不影响图像质量”调整图像大小:


UIImage *Resize_Image(UIImage *iImage, CGFloat iSize, CGFloat icornerRadius) {

    CGFloat scale = MAX(CGSizeMake(iSize ,iSize).width/iImage.size.width, CGSizeMake(iSize ,iSize).height/iImage.size.height);
    CGFloat width = iImage.size.width * scale;
    CGFloat height = iImage.size.height * scale;
    CGRect imageRect = CGRectMake((CGSizeMake(iSize ,iSize).width - width)/2.0f,(CGSizeMake(iSize ,iSize).height - height)/2.0f,width,height);
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(iSize ,iSize), NO, 0);
    [[UIBezierPath bezierPathWithRoundedRect:imageRect cornerRadius:icornerRadius] addClip];
    [iImage drawInRect:imageRect];
    UIImage *ResizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return ResizedImage;
}

This is how to use :这是如何使用:

UIImage *ResizedImage = Resize_Image([UIImage imageNamed:@"image.png"], 64, 14.4);
  • I do not remember where i took the first 4 lines ..我不记得我在哪里取了前 4 行..

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

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