wake-up-neo.com

Ändern Sie die Größe von UIImage, indem Sie das Seitenverhältnis und die Breite beibehalten

Ich habe in vielen Beiträgen gesehen, wie man die Größe des Bildes ändert, indem man das Seitenverhältnis beibehält. Diese Funktionen verwenden die festen Punkte (Breite und Höhe) für RECT während der Größenänderung. Aber in meinem Projekt muss ich die Ansicht nur basierend auf der Breite ändern. Höhe sollte automatisch basierend auf dem Seitenverhältnis übernommen werden.

127
Jasmine

Die Methode von Srikar funktioniert sehr gut, wenn Sie sowohl Höhe als auch Breite Ihrer neuen Größe kennen. Wenn Sie beispielsweise nur die Breite kennen, auf die Sie skalieren möchten, ist die Höhe, die Sie zuerst verwenden, nicht wichtig muss den Skalierungsfaktor der Höhe berechnen.

+(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;
}
226
Maverick1st

Wenn Sie nicht wissen, ob das Bild im Hoch- oder Querformat vorliegt (z. B. nimmt der Benutzer ein Bild mit der Kamera auf), habe ich eine andere Methode erstellt, die die Parameter für maximale Breite und Höhe berücksichtigt.

Nehmen wir an, Sie haben einen UIImage *myLargeImage, ein Verhältnis von 4: 3.

UIImage *myResizedImage = [ImageUtilities imageWithImage:myLargeImage 
                                        scaledToMaxWidth:1024 
                                               maxHeight:1024];

Der vergrößerte UIImage wird 1024x768 sein, wenn Querformat vorhanden ist. 768 x 1024 bei Hochformat. Diese Methode erzeugt auch Bilder mit höherer Auflösung für die Retina-Anzeige.

+ (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];
}
56
Ryan

Beste Antwort Maverick 1st ist korrekt übersetzt in Swift (arbeitet mit neuesten 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!
}
38

danke @ Maverick1st der Algorithmus, ich habe ihn inSwiftimplementiert, in meinem Fall ist height der Eingabeparameter

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
}
35
János

Diese Methode ist eine Kategorie in UIImage. Skaliert sich mit AVFoundation ..__ in wenigen Codezeilen. Vergessen Sie nicht, #import <AVFoundation/AVFoundation.h> zu importieren.

@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
18
mohamede1945

Am einfachsten ist es, den Rahmen Ihrer UIImageView und die contentMode auf eine der Größenänderungsoptionen einzustellen.

Der Code geht so - Dies kann als Dienstprogrammmethode verwendet werden -

+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
}
8

Programmatisch:

imageView.contentMode = UIViewContentModeScaleAspectFit;

Storyboard:

 enter image description here

5
Mona

Nun, wir haben hier nur wenige gute Antworten für die Größenanpassung von Bildern, aber ich ändere es einfach nach meinem Bedarf. hoffe das hilft jemandem wie mir.

Meine Anforderung war

  1. Wenn die Bildbreite mehr als 1920 beträgt, ändern Sie die Größe um 1920 mit der Breite und behalten Sie die Höhe mit dem ursprünglichen Seitenverhältnis bei.
  2. Wenn die Bildhöhe mehr als 1080 beträgt, ändern Sie die Größe mit 1080 Höhe und behalten Sie die Breite bei.

 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;
}

Danke an @ Srikar Appal , für die Größenänderung habe ich seine Methode verwendet.

Sie können auch this für die Berechnung der Größenänderung überprüfen.

5
swiftBoy

Importieren Sie einfach AVFoundation und verwenden Sie AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)

4
mariusLAN

Um die Antwort von Ryan zu verbessern:

   + (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];
    }
2
TheCodingArt

Swift 5 Version von Aspekt-Anpassung an -Höhe, basierend auf der Antwort von @ János

Verwendet die moderne UIGraphicsImageRenderer API, so dass eine gültige UIImage garantiert zurückkehrt.

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))
        }
    }
}

Sie können dies in Verbindung mit einem (vektorbasierten) PDF Bildasset verwenden, um die Qualität bei jeder Rendergröße zu erhalten.

2
Womble

In Swift 3 gibt es einige Änderungen. Hier ist eine Erweiterung zu 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
    }
}
1
Eridana

Ryan's Solution @Ryan Im Swift-Code

benutzen:

 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);
}
1
Daniel Krom

Berechnet die beste Höhe des Bildes für die verfügbare Breite.

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
    }
}
0
AshvinGudaliya

Dieser war perfekt für mich. Behält das Seitenverhältnis bei und nimmt eine maxLength. Breite oder Höhe ist nicht mehr als 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;
}
0
Zeeshan Tufail

Ich habe es viel einfacher gelöst

UIImage *placeholder = [UIImage imageNamed:@"OriginalImage.png"];
self.yourImageview.image = [UIImage imageWithCGImage:[placeholder CGImage] scale:(placeholder.scale * 1.5)
                                  orientation:(placeholder.imageOrientation)];

der Multiplikator der Skala definiert das Scalling des Bildes. Je kleiner der Multiplikator, desto kleiner das Bild. So können Sie überprüfen, was zu Ihrem Bildschirm passt.

Oder Sie können das Multi-Rire auch durch Teilen von Bildbreite/Bildschirmbreite erhalten.

0
Siddhant Saxena
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
    }
}

Wenn die Skalierung auf 0,0 eingestellt ist, wird der Skalierungsfaktor des Hauptbildschirms verwendet, der für Retina-Anzeigen 2,0 oder höher ist (3,0 beim iPhone 6 Plus).

0
oscarr