Изменение размера UIImage, сохраняя соотношение сторон и ширину
Я видел во многих постах для изменения размера изображения, сохраняя соотношение сторон. Эти функции используют фиксированные точки (ширину и высоту) для RECT при изменении размера. Но в моем проекте мне нужно изменить размер представления на основе только ширины, высота должна быть взята автоматически на основе соотношения сторон. кто-нибудь поможет мне достичь этого.
15 ответов
метод Srikar работает очень хорошо, если вы знаете как высота и ширина вашего нового размера. Если вы, например, знаете только ширину, которую хотите масштабировать, и не заботитесь о высоте, вам сначала нужно вычислить масштабный коэффициент высоты.
+(UIImage*)imageWithImage: (UIImage*) sourceImage scaledToWidth: (float) i_width
{
float oldWidth = sourceImage.size.width;
float scaleFactor = i_width / oldWidth;
float newHeight = sourceImage.size.height * scaleFactor;
float newWidth = oldWidth * scaleFactor;
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
[sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Если вы не знаете, будет ли изображение портретным или пейзажным (e.G пользователь делает снимок с камерой), я создал другой метод, который принимает максимальные параметры ширины и высоты.
допустим, у вас есть UIImage *myLargeImage
что соотношение 4:3.
UIImage *myResizedImage = [ImageUtilities imageWithImage:myLargeImage
scaledToMaxWidth:1024
maxHeight:1024];
измененный размер UIImage будет 1024x768, если пейзаж; 768x1024, если портрет. Этот метод также будет генерировать изображения с более высоким разрешением для retina-дисплея.
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size {
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(size, NO, [[UIScreen mainScreen] scale]);
} else {
UIGraphicsBeginImageContext(size);
}
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
+ (UIImage *)imageWithImage:(UIImage *)image scaledToMaxWidth:(CGFloat)width maxHeight:(CGFloat)height {
CGFloat oldWidth = image.size.width;
CGFloat oldHeight = image.size.height;
CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;
CGFloat newHeight = oldHeight * scaleFactor;
CGFloat newWidth = oldWidth * scaleFactor;
CGSize newSize = CGSizeMake(newWidth, newHeight);
return [ImageUtilities imageWithImage:image scaledToSize:newSize];
}
спасибо @Maverick1st алгоритм, я реализовал его в Swift
, в моем случае высота входной параметр
class func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage {
let scale = newHeight / image.size.height
let newWidth = image.size.width * scale
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
лучший ответ Maverick 1st's правильно переведен на Свифт (работает с последним swift 3):
func imageWithImage (sourceImage:UIImage, scaledToWidth: CGFloat) -> UIImage {
let oldWidth = sourceImage.size.width
let scaleFactor = scaledToWidth / oldWidth
let newHeight = sourceImage.size.height * scaleFactor
let newWidth = oldWidth * scaleFactor
UIGraphicsBeginImageContext(CGSize(width:newWidth, height:newHeight))
sourceImage.draw(in: CGRect(x:0, y:0, width:newWidth, height:newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
этот метод является категорией на UIImage. Масштабируется, чтобы соответствовать нескольким строкам кода с помощью AVFoundation.
Не забудьте импортировать #import <AVFoundation/AVFoundation.h>
.
@implementation UIImage (Helper)
- (UIImage *)imageScaledToFitToSize:(CGSize)size
{
CGRect scaledRect = AVMakeRectWithAspectRatioInsideRect(self.size, CGRectMake(0, 0, size.width, size.height));
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
[self drawInRect:scaledRect];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
@end
самый простой способ-установить рамки ваших UIImageView
и выберите contentMode
к одному из вариантов изменения размера.
код выглядит так - это можно использовать как метод утилиты -
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Ну, у нас есть несколько хороших ответов здесь для изменения размера изображения, но я просто изменяю в соответствии с моими потребностями. надеюсь, это поможет кому-то вроде меня.
мое требование
- если ширина изображения больше 1920, измените его размер с шириной 1920 и поддержанием высоты с исходным соотношением сторон.
- если высота изображения больше 1080, измените его размер с высотой 1080 и поддержанием ширины с исходным соотношением сторон.
if (originalImage.size.width > 1920)
{
CGSize newSize;
newSize.width = 1920;
newSize.height = (1920 * originalImage.size.height) / originalImage.size.width;
originalImage = [ProfileEditExperienceViewController imageWithImage:originalImage scaledToSize:newSize];
}
if (originalImage.size.height > 1080)
{
CGSize newSize;
newSize.width = (1080 * originalImage.size.width) / originalImage.size.height;
newSize.height = 1080;
originalImage = [ProfileEditExperienceViewController imageWithImage:originalImage scaledToSize:newSize];
}
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
спасибо @Устрашать Srikar для изменения размера я использовал свой метод.
вы можете проверить этой а также для расчета размера.
просто импортируйте AVFoundation и используйте AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)
чтобы улучшить ответ Райан:
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)size {
CGFloat oldWidth = image.size.width;
CGFloat oldHeight = image.size.height;
//You may need to take some retina adjustments into consideration here
CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;
return [UIImage imageWithCGImage:image.CGImage scale:scaleFactor orientation:UIImageOrientationUp];
}
решение Райана @Ryan в Свифт-код
использование:
func imageWithSize(image: UIImage,size: CGSize)->UIImage{
if UIScreen.mainScreen().respondsToSelector("scale"){
UIGraphicsBeginImageContextWithOptions(size,false,UIScreen.mainScreen().scale);
}
else
{
UIGraphicsBeginImageContext(size);
}
image.drawInRect(CGRectMake(0, 0, size.width, size.height));
var newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
//Summon this function VVV
func resizeImageWithAspect(image: UIImage,scaledToMaxWidth width:CGFloat,maxHeight height :CGFloat)->UIImage
{
let oldWidth = image.size.width;
let oldHeight = image.size.height;
let scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;
let newHeight = oldHeight * scaleFactor;
let newWidth = oldWidth * scaleFactor;
let newSize = CGSizeMake(newWidth, newHeight);
return imageWithSize(image, size: newSize);
}
Я решил это гораздо проще
UIImage *placeholder = [UIImage imageNamed:@"OriginalImage.png"];
self.yourImageview.image = [UIImage imageWithCGImage:[placeholder CGImage] scale:(placeholder.scale * 1.5)
orientation:(placeholder.imageOrientation)];
множитель масштаба будет определять масштабирование изображения, чем больше множитель меньше изображение. таким образом, вы можете проверить, что соответствует вашему экрану.
или вы также можете получить multiplire путем деления imagewidth/screenwidth.
на Swift 3 есть некоторые изменения. Вот расширение для UIImage:
public extension UIImage {
public func resize(height: CGFloat) -> UIImage? {
let scale = height / self.size.height
let width = self.size.width * scale
UIGraphicsBeginImageContext(CGSize(width: width, height: height))
self.draw(in: CGRect(x:0, y:0, width:width, height:height))
let resultImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return resultImage
}
}
Это было идеально для меня. Сохраняет соотношение сторон и принимает maxLength
. Ширина или высота не будет больше maxLength
-(UIImage*)imageWithImage: (UIImage*) sourceImage maxLength: (float) maxLength
{
CGFloat scaleFactor = maxLength / MAX(sourceImage.size.width, sourceImage.size.height);
float newHeight = sourceImage.size.height * scaleFactor;
float newWidth = sourceImage.size.width * scaleFactor;
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
[sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
вычисляет лучшую высоту изображения для доступной ширины.
import Foundation
public extension UIImage {
public func height(forWidth width: CGFloat) -> CGFloat {
let boundingRect = CGRect(
x: 0,
y: 0,
width: width,
height: CGFloat(MAXFLOAT)
)
let rect = AVMakeRect(
aspectRatio: size,
insideRect: boundingRect
)
return rect.size.height
}
}