我在许多文章中看到通过保持纵横比来调整图像大小 . 这些函数在调整大小时使用RECT的固定点(宽度和高度) . 但在我的项目中,我需要仅根据宽度调整视图大小,应根据宽高比自动获取高度 . 有人帮助我实现这一目标 .
如果你知道新尺寸的宽度,那么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; }
如果您不知道图像是纵向还是横向(例如用户使用相机拍照),我创建了另一种采用最大宽度和高度参数的方法 .
假设你有 UIImage *myLargeImage ,这是一个4:3的比例 .
UIImage *myLargeImage
UIImage *myResizedImage = [ImageUtilities imageWithImage:myLargeImage scaledToMaxWidth:1024 maxHeight:1024];
如果是风景,重新调整大小的UIImage将是1024x768; 768x1024如果肖像 . 该方法还将为视网膜显示生成更高分辨率的图像 .
+ (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]; }
最佳答案Maverick 1st正确翻译为 Swift (使用最新的 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! }
感谢@ Maverick1st算法,我实现了它 Swift ,在我的情况下,height是输入参数
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 }
此方法是UIImage上的一个类别 . 使用AVFoundation缩放以适应几行代码 . 别忘了导入 #import <AVFoundation/AVFoundation.h> .
#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 设置为其中一个调整大小选项 .
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; }
好吧,我们在这里没有很好的答案来调整图像大小,但我只是根据我的需要进行修改 . 希望这有助于像我这样的人 .
My Requirement was
如果图像宽度大于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 Appal,为了调整大小,我使用了他的方法 .
您可能还想检查this以进行调整大小计算 .
编程方式:
imageView.contentMode = UIViewContentModeScaleAspectFit;
故事板:
只需导入AVFoundation并使用 AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)
AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)
为了改进Ryan的答案:
+ (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的解决方案@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); }
在 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 } }
我用更简单的方式解决了这个问题
UIImage *placeholder = [UIImage imageNamed:@"OriginalImage.png"]; self.yourImageview.image = [UIImage imageWithCGImage:[placeholder CGImage] scale:(placeholder.scale * 1.5) orientation:(placeholder.imageOrientation)];
比例的乘数将定义图像的scalling,更多的乘数更小的图像 . 所以你可以检查什么适合你的屏幕 .
或者您也可以通过划分图像宽度/屏幕宽度来获得倍增 .
这个对我来说很完美 . 保持纵横比并采用 maxLength . 宽度或高度不会超过 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; }
Calculates the best height of the image for available width.
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 } }
extension UIImage { /// Returns a image that fills in newSize func resizedImage(newSize: CGSize) -> UIImage? { guard size != newSize else { return self } let hasAlpha = false let scale: CGFloat = 0.0 UIGraphicsBeginImageContextWithOptions(newSize, !hasAlpha, scale) UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0) draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage } /// Returns a resized image that fits in rectSize, keeping it's aspect ratio /// Note that the new image size is not rectSize, but within it. func resizedImageWithinRect(rectSize: CGSize) -> UIImage? { let widthFactor = size.width / rectSize.width let heightFactor = size.height / rectSize.height var resizeFactor = widthFactor if size.height > size.width { resizeFactor = heightFactor } let newSize = CGSize(width: size.width / resizeFactor, height: size.height / resizeFactor) let resized = resizedImage(newSize: newSize) return resized } }
当scale设置为0.0时,使用主屏幕的比例因子,Retina显示的比例因子为2.0或更高(iPhone 6 Plus上为3.0) .
16 回答
如果你知道新尺寸的宽度,那么Srikar的方法效果很好 . 例如,如果您只知道要缩放的宽度而不关心高度,则首先必须计算高度的比例因子 .
如果您不知道图像是纵向还是横向(例如用户使用相机拍照),我创建了另一种采用最大宽度和高度参数的方法 .
假设你有
UIImage *myLargeImage
,这是一个4:3的比例 .如果是风景,重新调整大小的UIImage将是1024x768; 768x1024如果肖像 . 该方法还将为视网膜显示生成更高分辨率的图像 .
最佳答案Maverick 1st正确翻译为 Swift (使用最新的 swift 3 ):
感谢@ Maverick1st算法,我实现了它 Swift ,在我的情况下,height是输入参数
此方法是UIImage上的一个类别 . 使用AVFoundation缩放以适应几行代码 . 别忘了导入
#import <AVFoundation/AVFoundation.h>
.最简单的方法是设置
UIImageView
的框架并将contentMode
设置为其中一个调整大小选项 .代码是这样的 - 这可以用作实用方法 -
好吧,我们在这里没有很好的答案来调整图像大小,但我只是根据我的需要进行修改 . 希望这有助于像我这样的人 .
My Requirement was
如果图像宽度大于1920,请使用1920宽度调整大小并使用原始高宽比保持高度 .
如果图像高度超过1080,请使用1080高度调整其大小并使用原始高宽比保持宽度 .
您可能还想检查this以进行调整大小计算 .
编程方式:
故事板:
只需导入AVFoundation并使用
AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)
为了改进Ryan的答案:
Ryan的解决方案@Ryan在快速代码中
使用:
在 Swift 3 中有一些变化 . 这是UIImage的扩展:
我用更简单的方式解决了这个问题
比例的乘数将定义图像的scalling,更多的乘数更小的图像 . 所以你可以检查什么适合你的屏幕 .
或者您也可以通过划分图像宽度/屏幕宽度来获得倍增 .
这个对我来说很完美 . 保持纵横比并采用
maxLength
. 宽度或高度不会超过maxLength
Calculates the best height of the image for available width.
当scale设置为0.0时,使用主屏幕的比例因子,Retina显示的比例因子为2.0或更高(iPhone 6 Plus上为3.0) .