アスペクト比を維持して画像のサイズを変更するための多くの投稿を見ました。これらの関数は、サイズ変更中に RECT の固定ポイント (幅と高さ) を使用します。しかし、私のプロジェクトでは、幅だけに基づいてビューのサイズを変更する必要があり、高さはアスペクト比に基づいて自動的に取得する必要があります。誰でも私がこれを達成するのを手伝ってくれます。
19 に答える
新しいサイズの高さと幅の両方がわかっている場合、スリカーの方法は非常にうまく機能します。たとえば、スケーリングしたい幅だけが分かっていて、高さは気にしない場合は、最初に高さの倍率を計算する必要があります。
+(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 *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
}
このメソッドは 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
最も簡単な方法は、フレームを設定し、サイズ変更オプションの 1 つに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;
}
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
}
}
scale を 0.0 に設定すると、メイン画面の倍率が使用されます。Retina ディスプレイでは 2.0 以上 (iPhone 6 Plus では 3.0) です。
私はそれをはるかに簡単な方法で解決しました
UIImage *placeholder = [UIImage imageNamed:@"OriginalImage.png"];
self.yourImageview.image = [UIImage imageWithCGImage:[placeholder CGImage] scale:(placeholder.scale * 1.5)
orientation:(placeholder.imageOrientation)];
スケールの乗数は画像のスケーリングを定義し、乗数が大きいほど画像は小さくなります。画面に合うものを確認できます。
または、imagewidth/screenwidth を割って乗数を取得することもできます。