2013-02-01 10 views
21

Mam to UIImageView i mam wartości jego maksymalnej wysokości i maksymalnej szerokości. Chcę uzyskać obraz (z dowolnym współczynnikiem kształtu i dowolną rozdzielczością) i chcę, aby pasował do obramowań, więc zdjęcie nie przekracza, ale może je skurczyć tak, jak chce . (Zaznaczone na czerwono na zdjęciu):Zmień rozmiar UIImage i zmień rozmiar UIImageView

enter image description here

Teraz obraz pasuje niezbędnej wielkości poprawnie, ale mam 2 zmartwień: 1. UIImageView nie jest równa wielkości obraz o zmienionym rozmiarze, pozostawiając czerwone tło (i tego nie chcę) 2. Jeśli obraz jest mniejszy niż wysokość mojego UIImageView, jego rozmiar nie jest zmniejszany, pozostaje na tej samej wysokości.

Oto mój kod i wiem, że jej źle:

UIImage *actualImage = [attachmentsArray lastObject]; 
UIImageView *attachmentImageNew = [[UIImageView alloc] initWithFrame:CGRectMake(5.5, 6.5, 245, 134)]; 
attachmentImageNew.image = actualImage; 
attachmentImageNew.backgroundColor = [UIColor redColor]; 
attachmentImageNew.contentMode = UIViewContentModeScaleAspectFit; 

Więc jak mam się dynamicznie zmieniać wielkość nie tylko z UIImageView.image, ale całego UIImageView, dzięki czemu jego rozmiar całkowicie regulowany do jego treści. Każda pomoc będzie bardzo ceniona, dzięki!

Odpowiedz

30

Kiedy uzyskać szerokość i wysokość zmienionym rozmiarze Get width of a resized image after UIViewContentModeScaleAspectFit można zmienić rozmiar ImageView:

imageView.frame = CGRectMake(0, 0, resizedWidth, resizedHeight); 
imageView.center = imageView.superview.center; 

Nie sprawdzałem czy to działa, ale myślę, że wszystko powinno być OK

+1

, jeśli po superview nie dodaję "!" daje mi błąd "wartość opcjonalnego typu" UIView? " nieopakowany "jest poprawiony, jeśli używam"! " : imageView.center = imageView.superview! .center; – Alex

+0

Co zrobić, jeśli używasz automatycznego układu? Czy nie powinieneś ustawiać "ramki"? –

1

Jeśli masz rozmiar obrazu, dlaczego nie ustawić frame.size widoku obrazu na taki rozmiar?

EDIT ----

Ok, więc widząc swój komentarz proponuję to:

UIImageView *imageView; 
//so let's say you're image view size is set to the maximum size you want 

CGFloat maxWidth = imageView.frame.size.width; 
CGFloat maxHeight = imageView.frame.size.height; 

CGFloat viewRatio = maxWidth/maxHeight; 
CGFloat imageRatio = image.size.height/image.size.width; 

if (imageRatio > viewRatio) { 
    CGFloat imageViewHeight = round(maxWidth * imageRatio); 
    imageView.frame = CGRectMake(0, ceil((self.bounds.size.height - imageViewHeight)/2.f), maxWidth, imageViewHeight); 
} 
else if (imageRatio < viewRatio) { 
    CGFloat imageViewWidth = roundf(maxHeight/imageRatio); 
    imageView.frame = CGRectMake(ceil((maxWidth - imageViewWidth)/2.f), 0, imageViewWidth, maxHeight); 
} else { 
    //your image view is already at the good size 
} 

Kod ten będzie zmienić rozmiar widoku obrazu do jego stosunek obrazu, a także ustawić widok obrazu do samym centrum, co twoja "domyślna" pozycja.

PS: Mam nadzieję, że ustawienie imageView.layer.shouldRasterise = YES i imageView.layer.rasterizationScale = [UIScreen mainScreen].scale;

jeśli używasz CALayer efekt cienia;) Będzie ona znacznie poprawić wydajność swojego interfejsu.

+0

Dlaczego sądzisz, że zmieniam rozmiar za pomocą 'attachmentImageNew.contentMode = UIViewContentModeScaleAspectFit'? Ponieważ obraz jest zbyt duży. Nie mogę ustawić rozmiaru 'imageView' jako dokładnego rozmiaru jego obrazu, ponieważ mam maksymalną wartość dla jego wysokości i szerokości. I prawie 90% zdjęć musi być zmieniana. –

0

Myślę, że to, czego chcesz, to inna content mode. Spróbuj użyć UIViewContentModeScaleToFill. Spowoduje to przeskalowanie zawartości, aby dopasować ją do rozmiaru UIImageView, zmieniając proporcje zawartości, jeśli to konieczne.

Zajrzyj do sekcji content mode na oficjalnym dokumencie, aby uzyskać lepszy obraz różnych dostępnych trybów zawartości (jest to ilustrowane obrazami).

+0

Próbowałem tego i wykracza poza granice mojego 'UIImageView' do galaktyki daleko stąd –

+0

To brzmi jak błąd z wojny gwiezdnej :-) – tiguero

+0

Cóż, to nie jest błąd, to po prostu zachowuje się tak, ja nie myślę, że potrzebuję 'contentMode' w ogóle, potrzebuję czegoś bardziej potężnego –

22
- (UIImage *)image:(UIImage*)originalImage scaledToSize:(CGSize)size 
{ 
    //avoid redundant drawing 
    if (CGSizeEqualToSize(originalImage.size, size)) 
    { 
     return originalImage; 
    } 

    //create drawing context 
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f); 

    //draw 
    [originalImage drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)]; 

    //capture resultant image 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    //return image 
    return image; 
} 
4

Użyj poniżej kategorię, a następnie zastosować obramowanie z Quartz do obrazu:

[yourimage.layer setBorderColor:[[UIColor whiteColor] CGColor]]; 
[yourimage.layer setBorderWidth:2]; 

Kategoria: UIImage + AutoScaleResize.h

#import <Foundation/Foundation.h> 

@interface UIImage (AutoScaleResize) 

- (UIImage *)imageByScalingAndCroppingForSize:(CGSize)targetSize; 

@end 

UIImage + AutoScaleResize.m

#import "UIImage+AutoScaleResize.h" 

@implementation UIImage (AutoScaleResize) 

- (UIImage *)imageByScalingAndCroppingForSize:(CGSize)targetSize 
{ 
    UIImage *sourceImage = self; 
    UIImage *newImage = nil; 
    CGSize imageSize = sourceImage.size; 
    CGFloat width = imageSize.width; 
    CGFloat height = imageSize.height; 
    CGFloat targetWidth = targetSize.width; 
    CGFloat targetHeight = targetSize.height; 
    CGFloat scaleFactor = 0.0; 
    CGFloat scaledWidth = targetWidth; 
    CGFloat scaledHeight = targetHeight; 
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0); 

    if (CGSizeEqualToSize(imageSize, targetSize) == NO) 
    { 
     CGFloat widthFactor = targetWidth/width; 
     CGFloat heightFactor = targetHeight/height; 

     if (widthFactor > heightFactor) 
     { 
      scaleFactor = widthFactor; // scale to fit height 
     } 
     else 
     { 
      scaleFactor = heightFactor; // scale to fit width 
     } 

     scaledWidth = width * scaleFactor; 
     scaledHeight = height * scaleFactor; 

     // center the image 
     if (widthFactor > heightFactor) 
     { 
      thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5; 
     } 
     else 
     { 
      if (widthFactor < heightFactor) 
      { 
       thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5; 
      } 
     } 
    } 

    UIGraphicsBeginImageContext(targetSize); // this will crop 

    CGRect thumbnailRect = CGRectZero; 
    thumbnailRect.origin = thumbnailPoint; 
    thumbnailRect.size.width = scaledWidth; 
    thumbnailRect.size.height = scaledHeight; 

    [sourceImage drawInRect:thumbnailRect]; 

    newImage = UIGraphicsGetImageFromCurrentImageContext(); 

    if(newImage == nil) 
    { 
     NSLog(@"could not scale image"); 
    } 

    //pop the context to get back to the default 
    UIGraphicsEndImageContext(); 

    return newImage; 
} 

@end 
6

To Swift ekwiwalent za odpowiedź Rajneesh071, wykorzystując rozszerzenia

UIImage { 
    func scaleToSize(aSize :CGSize) -> UIImage { 
    if (CGSizeEqualToSize(self.size, aSize)) { 
     return self 
    } 

    UIGraphicsBeginImageContextWithOptions(aSize, false, 0.0) 
    self.drawInRect(CGRectMake(0.0, 0.0, aSize.width, aSize.height)) 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return image 
    } 
} 

Zastosowanie:

let image = UIImage(named: "Icon") 
item.icon = image?.scaleToSize(CGSize(width: 30.0, height: 30.0)) 
+0

To zadziałało dla mnie! – thejuki

0
if([[SDWebImageManager sharedManager] diskImageExistsForURL:[NSURL URLWithString:@"URL STRING1"]]) 
    { 
     NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:[NSURL URLWithString:@"URL STRING1"]]; 

     UIImage *tempImage=[self imageWithImage:[[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key] scaledToWidth:cell.imgview.bounds.size.width]; 
     cell.imgview.image=tempImage; 

    } 
    else 
    { 
     [cell.imgview sd_setImageWithURL:[NSURL URLWithString:@"URL STRING1"] placeholderImage:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) 
     { 
      UIImage *tempImage=[self imageWithImage:image scaledToWidth:cell.imgview.bounds.size.width]; 
      cell.imgview.image=tempImage; 
//    [tableView beginUpdates]; 
//    [tableView endUpdates]; 

     }]; 
    } 
Powiązane problemy