调整图像大小时添加了细白线

时间:2011-05-21 11:18:29

标签: iphone objective-c image iphone-sdk-3.0

当我们调整图像大小时(下载后和存储在文档目录中之前),通过以下代码:

-(UIImage *)resizeImage:(UIImage *)image withSize:(CGSize)newSize
{
    float actualHeight = image.size.height;
    float actualWidth = image.size.width;
    float imgRatio = actualWidth/actualHeight;
    float maxRatio = newSize.width/newSize.height;

    if(imgRatio!=maxRatio){
        if(imgRatio < maxRatio){
            imgRatio = newSize.width / actualHeight;
            actualWidth = imgRatio * actualWidth;
            actualHeight = newSize.width;
        }
        else{
            imgRatio = newSize.height / actualWidth;
            actualHeight = imgRatio * actualHeight;
            actualWidth = newSize.height;
        }
    }
    CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
    UIGraphicsBeginImageContext(rect.size);
    [image drawInRect:rect];
    UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    //[resizedImage release];
    return [resizedImage autorelease];
}

这会生成一个重新调整大小的图像,并在其方向上添加了细白线(就好像图像是横向白色线条添加到它的底部,如果图像是肖像白色线条被添加到它的右手)。

请告诉我,如何摆脱那条白线?

谢谢。

2 个答案:

答案 0 :(得分:23)

虽然以浮点单位指定大小,但实际图像始终是整数像素。

当您计算新尺寸以保持纵横比时,通常只有一个边作为整数像素,而另一个尺度则具有一些小数部分。然后,当您将旧图像绘制到该矩形时,它不会完全填充新图像。所以你看到的白线是图形系统渲染像素的部分图像,部分背景。

从本质上讲,你想做的事情是不太可能的,所以你需要以某种方式捏造它。有几种可能性:

  • 缩放图像,使得宽高比不能完美保留,但您有整数值,例如通过舍入:

    actualWidth = round(imgRatio * actualWidth);
    
  • 保持纵横比但剪切小数边缘。最简单的方法是将图像上下文缩小一点:

    UIGraphicsBeginImageContext(CGSizeMake(floor(actualWidth), floor(actualHeight)));
    [image drawInRect:rect];
    
  • 首先用一些不如白色的颜色填充背景。显然,这是一个可怕的kludge,但在适当的情况下可能会有效,例如,如果你总是在黑色背景下绘制图像。

单独注意,您无法在return之后拨打任何内容,因此您的最终release行没有做任何事情。这也是因为从UIGraphicsGetImageFromCurrentImageContext返回的图像是自动释放的 - 无论如何你都不应该释放它。

答案 1 :(得分:0)

此代码将解决您的问题:

+ (UIImage *)scaleImageProportionally:(UIImage *)image {

if (MAX(image.size.height, image.size.width) <= DEFAULT_PHOTO_MAX_SIZE) {
    return image;
}
else {
    CGFloat targetWidth = 0;
    CGFloat targetHeight = 0;
    if (image.size.height > image.size.width) {
        CGFloat ratio = image.size.height / image.size.width;
        targetHeight = DEFAULT_PHOTO_MAX_SIZE;
        targetWidth = roundf(DEFAULT_PHOTO_MAX_SIZE/ ratio);
    }
    else {
        CGFloat ratio = image.size.width / image.size.height;
        targetWidth = DEFAULT_PHOTO_MAX_SIZE;
        targetHeight = roundf(DEFAULT_PHOTO_MAX_SIZE/ ratio);
    }

    CGSize targetSize = CGSizeMake(targetWidth, targetHeight);

    UIImage *sourceImage = image;
    UIImage *newImage = nil;

    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;

    targetWidth = targetSize.width;
    targetHeight = targetSize.height;

    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;

    CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);

    if (!CGSizeEqualToSize(imageSize, targetSize)) {

        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;

        if (widthFactor < heightFactor)
            scaleFactor = widthFactor;
        else
            scaleFactor = heightFactor;

        scaledWidth = roundf(width * scaleFactor);
        scaledHeight = roundf(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);

    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width = scaledWidth;
    thumbnailRect.size.height = scaledHeight;

    [sourceImage drawInRect:thumbnailRect];

    newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    if (newImage == nil) NSLog(@"could not scale image");

    return newImage;
}
}