Resize and crop images before displaying in UITableViewCells

后端 未结 2 1590
鱼传尺愫
鱼传尺愫 2021-02-04 22:49

i have an UITableView in my app and i have to load some images that have a fixed width but different heights. I download the images async using an NSOperationQueue and for resiz

相关标签:
2条回答
  • 2021-02-04 23:20

    this is what i'm using for resizing and croping the UIImages (the code is from Jane Sales solution)

    @implementation UIImage (Extras) 
    #pragma mark -
    #pragma mark Scale and crop image
    
    - (UIImage*)imageByScalingAndCroppingForSize:(CGSize)targetSize
    {
    UIImage *sourceImage = self;
    UIImage *newImage = nil;        
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
    
    if (CGSizeEqualToSize(imageSize, targetSize) == NO) 
            {
            CGFloat widthFactor = targetWidth / width;
            CGFloat heightFactor = targetHeight / height;
    
            if (widthFactor > heightFactor) 
                    scaleFactor = widthFactor; // scale to fit height
            else
                    scaleFactor = heightFactor; // scale to fit width
            scaledWidth  = width * scaleFactor;
            scaledHeight = height * scaleFactor;
    
            // center the image
            if (widthFactor > heightFactor)
                    {
                    thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
                    }
            else 
                    if (widthFactor < heightFactor)
                            {
                            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
                            }
            }       
    
    UIGraphicsBeginImageContext(targetSize); // this will crop
    
    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width  = scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    
    [sourceImage drawInRect:thumbnailRect];
    
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    if(newImage == nil) 
            NSLog(@"could not scale image");
    
    //pop the context to get back to the default
    UIGraphicsEndImageContext();
    return newImage;
    }
    

    i call the above function like i said before:

    - (void) setupImage:(UIImage *) anImage
    {
        UIImage *resized = [anImage imageByScalingAndCroppingForSize:CGSizeMake(64, 59)];
        [thumbnailView setImage:resized];
    }
    

    the images are downloaded async when a cell is displayed in the table view. the setupImage function receives the image from an NSOperation that downloads it async. the problem is, like i said above, when it reaches [sourceImage drawInRect:thumbnailRect];

    thumbnailView is an UIImageView that is a subview of my custom TableViewCell.

    hope this clears things a bit about what i'm using in my code. Thank you for the help. Sorin

    0 讨论(0)
  • 2021-02-04 23:27

    Try the following code. The createImage:image:width:height method requires a source CGImageRef and the new width and height of the final UIImage that will be returned. When using as source an UIImage, you can obtain the corresponding CGImageRef as follows:

    UIImage *sourceImage;
    CGImageRef *sourceRef = [sourceImage CGImage];
    
            // Draw the image into a pixelsWide x pixelsHigh bitmap and use that bitmap to 
            // create a new UIImage 
            - (UIImage *) createImage: (CGImageRef) image width: (int) pixelWidth height: (int) pixelHeight
            { 
                // Set the size of the output image 
                CGRect aRect = CGRectMake(0.0f, 0.0f, pixelWidth, pixelHeight); 
                // Create a bitmap context to store the new thumbnail 
                CGContextRef context = MyCreateBitmapContext(pixelWidth, pixelHeight); 
                // Clear the context and draw the image into the rectangle 
                CGContextClearRect(context, aRect); 
                CGContextDrawImage(context, aRect, image); 
                // Return a UIImage populated with the new resized image 
                CGImageRef myRef = CGBitmapContextCreateImage (context); 
    
                UIImage *img = [UIImage imageWithCGImage:myRef];
    
                free(CGBitmapContextGetData(context)); 
                CGContextRelease(context);
                CGImageRelease(myRef);
    
                return img; 
            } 
    
    
    
            // MyCreateBitmapContext: Source based on Apple Sample Code
            CGContextRef MyCreateBitmapContext (int pixelsWide,
                                                int pixelsHigh)
            {
                CGContextRef    context = NULL;
                CGColorSpaceRef colorSpace;
                void *          bitmapData;
                int             bitmapByteCount;
                int             bitmapBytesPerRow;
    
                bitmapBytesPerRow   = (pixelsWide * 4);
                bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
    
                colorSpace = CGColorSpaceCreateDeviceRGB();
                bitmapData = malloc( bitmapByteCount );
                if (bitmapData == NULL)
                {
                    fprintf (stderr, "Memory not allocated!");
                    CGColorSpaceRelease( colorSpace );
                    return NULL;
                }
                context = CGBitmapContextCreate (bitmapData,
                                                 pixelsWide,
                                                 pixelsHigh,
                                                 8,
                                                 bitmapBytesPerRow,
                                                 colorSpace,
                                                 kCGImageAlphaPremultipliedLast);
                if (context== NULL)
                {
                    free (bitmapData);
                    CGColorSpaceRelease( colorSpace );
                    fprintf (stderr, "Context not created!");
                    return NULL;
                }
                CGColorSpaceRelease( colorSpace );
    
                return context;
            }
    
    0 讨论(0)
提交回复
热议问题