2011-10-04 15 views
112

Ho visto in molti post il ridimensionamento dell'immagine mantenendo le proporzioni. Queste funzioni utilizzano i punti fissi (Larghezza e Altezza) per RECT durante il ridimensionamento. Ma nel mio progetto, ho bisogno di ridimensionare la vista in base alla sola larghezza, l'altezza dovrebbe essere presa automaticamente in base al rapporto di aspetto. chiunque mi aiuti a raggiungere questo obiettivo.Ridimensiona UIImage mantenendo Aspect ratio e width

risposta

215

Il metodo di Srikar funziona molto bene, se si sa sia in altezza e la larghezza del nuovo formato. Se per esempio conosci solo la larghezza su cui vuoi scalare e non ti interessa l'altezza, devi prima calcolare il fattore di scala dell'altezza.

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

In questo caso non hai davvero bisogno della variabile 'newWidth', è già' i_width'. –

+2

Devi dividere anche per altezza e confrontare i fattori di scala usando il valore più vicino a 0. il codice sopra funzionerà solo con immagini più larghe di quanto siano alte – IceForge

+1

Avrei solo bisogno di dividere per altezza se volessi conoscere anche il mio rapporto di altezza e adattarlo ridimensionando la larghezza o l'altezza. ma poiché il TO ha chiesto esplicitamente di mantenere il rapporto e la larghezza, e non la larghezza o l'altezza, la mia risposta è completamente corretta. – Maverick1st

8

Il modo più semplice è impostare la cornice del proprio UIImageView e impostare contentMode su una delle opzioni di ridimensionamento.

Il codice va come questo - Questo può essere usato come un metodo di utilità -

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

Sono riuscito a farlo funzionare semplicemente impostando 'contentMode'. –

54

Se non capita di sapere se l'immagine sarà orizzontale o verticale (per esempio utente prende pic con la macchina fotografica), ho creato un altro metodo che prende parametri di larghezza e altezza max.

Diciamo che hai un UIImage *myLargeImage che è un rapporto 4: 3.

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

L'UIImage ridimensionata sarà 1024x768 se paesaggio; 768x1024 se ritratto. Questo metodo genererà anche immagini ad alta risoluzione per la visualizzazione della 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]; 
} 
+0

Grazie. Questo è proprio quello che stavo cercando! – SeanK

+0

GRAZIE GRAZIE! – 4GetFullOf

+1

Questa è la cosa migliore ma restituisce sempre il doppio della dimensione definita – Mashhadi

4

Basta importare AVFoundation e utilizzare AVMakeRectWithAspectRatioInsideRect(CGRectCurrentSize, CGRectMake(0, 0, YOUR_WIDTH, CGFLOAT_MAX)

2

Per migliorare la risposta di 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]; 
    } 
31

grazie @ Maverick1st l'algoritmo, ho implementato a Swift, nella mia altezza caso è il parametro di input

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

Questo metodo è una categoria su UIImage. Scala per adattarsi a poche righe di codice utilizzando AVFoundation. Non dimenticare di importare #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 
+2

Trovato questo per dare i migliori risultati per me con il minimo ingombro di memoria. +1 –

+1

Fantastico superbo, grazie mille. –

1

Soluzione @ Ryan Ryan in codice swift

uso:

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

Bene, abbiamo alcune buone risposte qui per il ridimensionamento delle immagini, ma ho appena modificare come per il mio bisogno. Spero che questo aiuti qualcuno come me.

La mia esigenza era

  1. Se la larghezza dell'immagine è superiore a 1920, ridimensionarlo con 1920 larghezza e l'altezza mantenendo con proporzioni originali.
  2. Se l'altezza dell'immagine è superiore a 1080, ridimensionala con altezza 1080 e mantenendo la larghezza con proporzioni originali.

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

Grazie a @Srikar Appal, per il ridimensionamento ho usato il suo metodo.

È possibile controllare anche il this per il calcolo del ridimensionamento.

0

ho risolto in un modo molto più semplice

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

moltiplicatore della scala definirà la scalling dell'immagine, più il moltiplicatore minore dell'immagine. così puoi controllare che cosa si adatta al tuo schermo.

Oppure puoi anche ottenere il multiplire dividendo larghezza di immagine/larghezza di schermo.

32

Miglior risposta Maverick prima correttamente tradotto in Swift (lavorare con l'ultima rapida 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! 
} 
5

di programmazione:

imageView.contentMode = UIViewContentModeScaleAspectFit; 

Storyboard:

enter image description here

0

In Swift 3 ci sono alcuni cambiamenti. Qui è un'estensione per 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 
    } 
} 
0

Questo era perfetto per me. Mantiene le proporzioni e prende un maxLength. Larghezza o Altezza non sarà superiore a 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; 
} 
Problemi correlati