来自UIImagePickerViewController图像的方形缩略图 [英] Square thumbnail from UIImagePickerViewController image

查看:78
本文介绍了来自UIImagePickerViewController图像的方形缩略图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用中,用户使用UIImagePickerViewController选择图像或拍照。一旦图像被选中,我想在方形UIImageView(90x90)上显示它的缩略图。



我正在使用 Apple的代码到创建缩略图。问题是缩略图没有平方,函数在设置kCGImageSourceThumbnailMaxPixelSize键后为90,似乎只调整图像的高度,据我所知,kCGImageSourceThumbnailMaxPixelSize键应该负责设置缩略图的高度和宽度。 / p>

以下是我的代码的一瞥:

   - (void) imagePickerController:(UIImagePickerController *)picker 
didFinishPickingMediaWithInfo:(NSDictionary *)info {

UIImage * image = [info objectForKey:UIImagePickerControllerOriginalImage];

NSData * imageData = UIImageJPEGRepresentation(image,0.5);

//我的图像视图是90x90
UIImage * thumbImage = MyCreateThumbnailImageFromData(imageData,90);

[myImageView setImage:thumbImage];

if(picker.sourceType == UIImagePickerControllerSourceTypeCamera){

UIImageWriteToSavedPhotosAlbum(image,self,@ selector(image:didFinishSavingWithError:contextInfo :),nil);
}

[picker dismissViewControllerAnimated:YES completion:nil];
}

UIImage * MyCreateThumbnailImageFromData(NSData * data,int imageSize){

CGImageRef myThumbnailImage = NULL;
CGImageSourceRef myImageSource;
CFDictionaryRef myOptions = NULL;
CFStringRef myKeys [3];
CFTypeRef myValues [3];
CFNumberRef thumbnailSize;

//从NSData创建图像源;没有选择。
myImageSource = CGImageSourceCreateWithData((__ bridge CFDataRef)data,
NULL);

//在继续之前确保图像源存在。
if(myImageSource == NULL){
fprintf(stderr,Image source is NULL。);
返回NULL;
}

//将整数打包为CFNumber对象。使用CFTypes允许
//以便以后更轻松地创建选项字典。
thumbnailSize = CFNumberCreate(NULL,kCFNumberIntType,& imageSize);

//设置缩略图选项。
myKeys [0] = kCGImageSourceCreateThumbnailWithTransform;
myValues [0] =(CFTypeRef)kCFBooleanTrue;
myKeys [1] = kCGImageSourceCreateThumbnailFromImageIfAbsent;
myValues [1] =(CFTypeRef)kCFBooleanTrue;
myKeys [2] = kCGImageSourceThumbnailMaxPixelSize;
myValues [2] = thumbnailSize;

myOptions = CFDictionaryCreate(NULL,(const void **)myKeys,
(const void **)myValues,2,
& kCFTypeDictionaryKeyCallBacks,
& kCFTypeDictionaryValueCallBacks);

//使用指定的选项创建缩略图图像。
myThumbnailImage = CGImageSourceCreateThumbnailAtIndex(myImageSource,
0,
myOptions);

UIImage * scaled = [UIImage imageWithCGImage:myThumbnailImage];

//当您不再需要时,释放选项字典和图像源
//。

CFRelease(thumbnailSize);
CFRelease(myOptions);
CFRelease(myImageSource);

//确保缩略图存在,然后再继续。
if(myThumbnailImage == NULL){
fprintf(stderr,缩略图图像不是从图像源创建的。);
返回NULL;
}
返回缩放;
}

这就是我的图片视图的实例化方式:

  myImageView = [[UIImageView alloc] init]; 
imageView.contentMode = UIViewContentModeScaleAspectFit;

CGRect rect = imageView.frame;
rect.size.height = 90;
rect.size.width = 90;

imageView.frame = rect;
[imageView setUserInteractionEnabled:YES];

如果我没有设置 imageView.contentMode = UIViewContentModeScaleAspectFit; 缩略图会失真,因为它只是我原始图像的一个版本,高度为90像素。



那么,为什么我的缩略图不平方?

解决方案

最简单的方法是设置 contentMode 您的imageView将是 UIViewContentModeScaleAspectFill 。但是,这可能并不理想,因为它会将整个图像保留在内存中。



这是我用来调整图像大小的一些代码。

  +(UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size 
{
UIGraphicsBeginImageContextWithOptions(size,NO, 0);
[image drawInRect:CGRectMake(0,0,size.width,size.height)];
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
返回newImage;
}

如果尺寸不同,此版本将保持图像失真宽高比作为图像。

  +(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();
返回newImage;
}

通常你只想要一个顶部正方形图像(而不是中心)。并且您希望最终图像具有特定大小,例如128x128,如下例所示。

   - (UIImage * )squareAndSmall //作为一个类别(所以,'self'是输入图像)
{
// fromCleverError的原始
// http://stackoverflow.com/questions/17884555
CGSize finalsize = CGSizeMake(128,128);

CGFloat scale = MAX(
finalsize.width / self.size.width,
finalsize.height / self.size.height);
CGFloat width = self.size.width * scale;
CGFloat height = self.size.height * scale;

CGRect rr = CGRectMake(0,0,width,height);

UIGraphicsBeginImageContextWithOptions(finalsize,NO,0);
[self drawInRect:rr];
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
返回newImage;
}


In my app the user selects an image or take a picture using UIImagePickerViewController. Once the image was selected I want to display its thumbnail on a square UIImageView (90x90).

I'm using Apple's code to create a thumbnail. The problem is the thumbnail is not squared, the function, after set kCGImageSourceThumbnailMaxPixelSize key to 90, seems only to resize the image's height, and as far as I know the kCGImageSourceThumbnailMaxPixelSize key should be responsible for setting the height and width of the thumbnail.

Here is a glimpse of my code:

- (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary *)info {

    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];

    NSData *imageData = UIImageJPEGRepresentation (image, 0.5);

    // My image view is 90x90
    UIImage *thumbImage = MyCreateThumbnailImageFromData(imageData, 90);

    [myImageView setImage:thumbImage];

    if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {

        UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    }

    [picker dismissViewControllerAnimated:YES completion:nil];
}

UIImage* MyCreateThumbnailImageFromData (NSData * data, int imageSize) {

    CGImageRef        myThumbnailImage = NULL;
    CGImageSourceRef  myImageSource;
    CFDictionaryRef   myOptions = NULL;
    CFStringRef       myKeys[3];
    CFTypeRef         myValues[3];
    CFNumberRef       thumbnailSize;

    // Create an image source from NSData; no options.
    myImageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data,
                                                NULL);

    // Make sure the image source exists before continuing.
    if (myImageSource == NULL){
        fprintf(stderr, "Image source is NULL.");
        return  NULL;
    }

    // Package the integer as a  CFNumber object. Using CFTypes allows you
    // to more easily create the options dictionary later.
    thumbnailSize = CFNumberCreate(NULL, kCFNumberIntType, &imageSize);

    // Set up the thumbnail options.
    myKeys[0] = kCGImageSourceCreateThumbnailWithTransform;
    myValues[0] = (CFTypeRef)kCFBooleanTrue;
    myKeys[1] = kCGImageSourceCreateThumbnailFromImageIfAbsent;
    myValues[1] = (CFTypeRef)kCFBooleanTrue;
    myKeys[2] = kCGImageSourceThumbnailMaxPixelSize;
    myValues[2] = thumbnailSize;

    myOptions = CFDictionaryCreate(NULL, (const void **) myKeys,
                                   (const void **) myValues, 2,
                                   &kCFTypeDictionaryKeyCallBacks,
                                   & kCFTypeDictionaryValueCallBacks);

    // Create the thumbnail image using the specified options.
    myThumbnailImage = CGImageSourceCreateThumbnailAtIndex(myImageSource,
                                                           0,
                                                           myOptions);

    UIImage* scaled = [UIImage imageWithCGImage:myThumbnailImage];

    // Release the options dictionary and the image source
    // when you no longer need them.

    CFRelease(thumbnailSize);
    CFRelease(myOptions);
    CFRelease(myImageSource);

    // Make sure the thumbnail image exists before continuing.
    if (myThumbnailImage == NULL) {
        fprintf(stderr, "Thumbnail image not created from image source.");
        return NULL;
    }
    return scaled;
}

And this how my image view is instantiated:

myImageView = [[UIImageView alloc] init];
imageView.contentMode = UIViewContentModeScaleAspectFit;

CGRect rect = imageView.frame;
rect.size.height = 90;
rect.size.width = 90;

imageView.frame = rect;
[imageView setUserInteractionEnabled:YES];

If I don't set imageView.contentMode = UIViewContentModeScaleAspectFit; the thumbnail will be distorted, since it is just a version of my original image with height of 90 pixels.

So, why is my thumbnail not squared?

解决方案

The easiest thing to do would be to set the contentMode on your imageView to be UIViewContentModeScaleAspectFill instead. However, this may not be ideal since it would keep the whole image in memory.

Here is some code that I use to resize images.

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size
{
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}

This version will keep the image from being distorted if the size is not the same aspect ratio as the image.

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

Often you want just the top square of an image (rather than the center). And you want the final image to be of a certain size, say 128x128, like in the example below.

- (UIImage *)squareAndSmall // as a category (so, 'self' is the input image)
{
    // fromCleverError's original
    // http://stackoverflow.com/questions/17884555
    CGSize finalsize = CGSizeMake(128,128);

    CGFloat scale = MAX(
        finalsize.width/self.size.width,
        finalsize.height/self.size.height);
    CGFloat width = self.size.width * scale;
    CGFloat height = self.size.height * scale;

    CGRect rr = CGRectMake( 0, 0, width, height);

    UIGraphicsBeginImageContextWithOptions(finalsize, NO, 0);
    [self drawInRect:rr];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}

这篇关于来自UIImagePickerViewController图像的方形缩略图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆