我在很多文章中都看到过通过保持宽高比来调整图像大小。这些函数在调整大小时使用RECT的固定点(宽度和高度)。但是在我的项目中,我需要仅根据宽度调整视图大小,应根据宽高比自动获取高度。 任何人帮助我实现这一目标。
答案 0 :(得分:226)
如果您知道新尺寸的高度和宽度,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;
}
答案 1 :(得分:56)
如果您不知道图像是纵向还是横向(例如用户使用相机拍照),我创建了另一种采用最大宽度和高度参数的方法。
假设您有一个UIImage *myLargeImage
比例为4:3。
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];
}
答案 2 :(得分:38)
最佳答案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!
}
答案 3 :(得分:36)
感谢@ 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
}
答案 4 :(得分:18)
此方法是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
答案 5 :(得分:7)
最简单的方法是设置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;
}
答案 6 :(得分:5)
嗯,我们这里没有很好的答案来调整图像大小,但我只是根据需要进行修改。希望这能帮到像我这样的人。
我的要求是
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以及调整大小计算。
答案 7 :(得分:5)
答案 8 :(得分:4)
只需导入AVFoundation并使用AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)
答案 9 :(得分:2)
改进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];
}
答案 10 :(得分:1)
使用:
while (infile >> s >> a[0] >> a[1] >> a[2]) {
...
}
答案 11 :(得分:1)
在 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
}
}
答案 12 :(得分:1)
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
}
}
当比例设置为0.0时,将使用主屏幕的比例因子,对于Retina显示屏,该比例因子为2.0或更高(iPhone 6 Plus为3.0)。
答案 13 :(得分:0)
如果有人在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
}
答案 14 :(得分:0)
Zeeshan Tufail和Womble在 Swift 5 中的答案有所改进。
这里我们有2个功能扩展,可以将图像缩放到任意尺寸的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)
}
}
答案 15 :(得分:0)
Swift 5 版本的宽高比高度,基于@János的回答
使用现代的UIGraphicsImageRenderer
API,因此可以保证返回有效的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图像资产结合使用,以保持任何渲染尺寸的质量。
答案 16 :(得分:0)
计算可用宽度的图像最佳高度。
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
}
}
答案 17 :(得分:0)
这个对我来说很完美。保持宽高比并获得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;
}
答案 18 :(得分:-1)
我用更简单的方式解决了它
UIImage *placeholder = [UIImage imageNamed:@"OriginalImage.png"];
self.yourImageview.image = [UIImage imageWithCGImage:[placeholder CGImage] scale:(placeholder.scale * 1.5)
orientation:(placeholder.imageOrientation)];
比例的乘数将定义图像的scalling,更多的乘数更小的图像。所以你可以检查一下你的屏幕是什么。
或者您也可以通过划分图像宽度/屏幕宽度来获得倍数。