我在许多帖子中看到通过保持长宽比来调整图像的大小。这些函数在调整大小时使用 RECT 的固定点(Width 和 Height)。但是在我的项目中,我需要调整视图的宽度单独,高度应采取自动根据纵横比。 任何人帮助我实现这一点。
最简单的方法是设置 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; }
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]; }
只需导入 AVFoundation 并使用 AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)
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]; }
感谢@Maverick1的算法,我实现它到 Swift,在我的情况下高度是输入参数
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 }
此方法是 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
解决方案@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); }
嗯,我们在这里有几个很好的答案调整图像,但我只是根据我的需要修改。希望这能帮到像我这样的人。
我的要求是
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,为了调整大小,我使用了他的方法。
您也可以检查 这个以进行大小调整计算。
我已经用更简单的方法解决了
UIImage *placeholder = [UIImage imageNamed:@"OriginalImage.png"]; self.yourImageview.image = [UIImage imageWithCGImage:[placeholder CGImage] scale:(placeholder.scale * 1.5) orientation:(placeholder.imageOrientation)];
尺度的乘法器将定义图像的尺度,越乘法器越小的图像。所以你可以检查什么适合你的屏幕。
或者你也可以通过除以图像宽度/屏幕宽度得到乘法。
最佳答案 Maverick 1的正确翻译为 斯威夫特(使用最新的 雨燕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! }
程序设计:
imageView.contentMode = UIViewContentModeScaleAspectFit;
故事板:
在 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
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 } }
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) 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 } }
当比例设置为0.0时,使用主屏幕的比例因子,视网膜显示器的比例因子为2.0或更高(iPhone 6 Plus 的比例因子为3.0)。
Swift 5 版本的方面适合 身高,基于@J ános 的回答
使用现代的 UIGraphicsImageRenderer API,因此保证返回有效的 UIImage。
UIGraphicsImageRenderer
UIImage
extension UIImage { /// Given a required height, returns a (rasterised) copy /// of the image, aspect-fitted to that height. func aspectFittedToHeight(_ newHeight: CGFloat) -> UIImage { let scale = newHeight / self.size.height let newWidth = self.size.width * scale let newSize = CGSize(width: newWidth, height: newHeight) let renderer = UIGraphicsImageRenderer(size: newSize) return renderer.image { _ in self.draw(in: CGRect(origin: .zero, size: newSize)) } } }
您可以结合使用这个(基于矢量的) PDF 图像资产,以保持任何渲染大小的质量。
Zeeshan Tufall 和 Womble 在 Swift 5中的回答有一些小的改进。 这里我们有两个扩展函数来缩放图像到任意维度的 maxLength和 jpeg 压缩。
extension UIImage { func aspectFittedToMaxLengthData(maxLength: CGFloat, compressionQuality: CGFloat) -> Data { let scale = maxLength / max(self.size.height, self.size.width) let format = UIGraphicsImageRendererFormat() format.scale = scale let renderer = UIGraphicsImageRenderer(size: self.size, format: format) return renderer.jpegData(withCompressionQuality: compressionQuality) { context in self.draw(in: CGRect(origin: .zero, size: self.size)) } } func aspectFittedToMaxLengthImage(maxLength: CGFloat, compressionQuality: CGFloat) -> UIImage? { let newImageData = aspectFittedToMaxLengthData(maxLength: maxLength, compressionQuality: compressionQuality) return UIImage(data: newImageData) } }
如果有人在 Swift 5中需要这个解决方案:
private func resizeImage(image: UIImage, newHeight: CGFloat) -> UIImage { let scale = newHeight / image.size.height let newWidth = image.size.width * scale UIGraphicsBeginImageContext(CGSize(width:newWidth, height:newHeight)) image.draw(in:CGRect(x:0, y:0, width:newWidth, height:newHeight)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage }