При изменении размера изображения добавляется тонкая whiteline
При изменении размера изображения (после загрузки и перед сохранением в каталоге документа) следующим кодом:
-(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];
}
это создает изображение с размерами с тонкой белой линией, добавленной к ней, как если бы изображение было добавлено к нижней части пейзажной белой линии, а если изображение - вертикальная белая линия, добавленная к ней правой рукой).
скажите, что, как избавиться от этой белой линии?
Спасибо.
Ответы
Ответ 1
Хотя размер указан в единицах с плавающей запятой, фактическое изображение всегда является целым числом пикселей.
Когда вы вычисляете новый размер, чтобы сохранить соотношение сторон, вы, как правило, будете иметь только одну из сторон как целое число пикселей, в то время как другие шкалы имеют некоторую дробную часть. Когда вы затем рисуете старое изображение в этом прямоугольнике, оно не совсем заполняет новое изображение. Так что вы видите как белую линию - это способ графической системы рендеринга пикселей, которые являются частью изображения, частью фона.
В сущности, то, что вы хотите сделать, не совсем возможно, поэтому вам нужно как-то выманить его. Существует несколько возможностей:
-
Масштабируйте изображение таким образом, чтобы соотношение сторон не было полностью сохранено, но у вас есть целые значения, например округление:
actualWidth = round(imgRatio * actualWidth);
-
Поддерживайте соотношение сторон, но зажимайте дробный край. Самый простой способ сделать это, вероятно, сделать контекст изображения немного меньше:
UIGraphicsBeginImageContext(CGSizeMake(floor(actualWidth), floor(actualHeight)));
[image drawInRect:rect];
-
Просто заполните фон сначала цветом, который менее очевидным, чем белый. Очевидно, это ужасный kludge, но может быть эффективным при правильных обстоятельствах, например, если вы всегда рисуете изображение на черном фоне.
В отдельном примечании вы не можете ничего вызывать после return
, поэтому ваша окончательная строка release
ничего не делает. Это так же хорошо, потому что изображение, возвращаемое с UIGraphicsGetImageFromCurrentImageContext
, автореализовано - вы все равно не должны его выпускать.
Ответ 2
Этот код исправит вашу проблему:
+ (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;
}
}