Bagaimana skala UIImageView secara proporsional?

341

Saya memiliki UIImageView dan tujuannya adalah untuk menurunkannya secara proporsional dengan memberikan ketinggian atau lebar.

UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3092/2915896504_a88b69c9de.jpg"]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 

//Add image view
[self.view addSubview:imageView];   

//set contentMode to scale aspect to fit
imageView.contentMode = UIViewContentModeScaleAspectFit;

//change width of frame
CGRect frame = imageView.frame;
frame.size.width = 100;
imageView.frame = frame;

Gambar memang diubah ukurannya tetapi posisinya tidak di kiri atas. Apa pendekatan terbaik untuk penskalaan gambar / imageView dan bagaimana cara memperbaiki posisi?

Ronnie Liew
sumber
Saya memiliki sesuatu yang mirip dengan kode Anda yang tidak berfungsi untuk saya "UIImage * image = [UIImage imageNamed: imageString]; UIImageView * imageView = [[alokasi UIImage] initWithImage: image];" membeberkan pengecualian yang membunuh aplikasi saya dengan "Pengakhiran aplikasi karena pengecualian tanpa tertangkap 'NSInvalidArgumentException', alasan: '- [UIImage initWithImage:]: pemilih yang tidak dikenal dikirim ke instance 0xd815930'"
Spire
3
@Spire Ini UIImageView bukan UIImage ^^
Thomas Decaux
2
Ini bekerja untuk saya. Ingatlah untuk mengatur .contentMode ke UIImageView Anda - bukan UIImage Anda. - Ini milik saya: UIImageView * imageView = [[alokasi UIImageView] initWithFrame: CGRectMake (0,0,30,30)]
Jarrett Barnett

Jawaban:

541

Diperbaiki dengan mudah, begitu saya menemukan dokumentasi!

 imageView.contentMode = UIViewContentModeScaleAspectFit;
Ken Abrams
sumber
19
Apa yang sebenarnya Anda jawab? dalam pertanyaan Ronnie, dia menyebutkan bahwa dia menggunakannya
Dejell
3
ImageView Anda mungkin tidak terpotong. Coba imageView.layer.masksToBounds = YA;
mackworth
Saya pertama kali mencoba dengan IB untuk memastikan itu akan berfungsi sesuai kebutuhan, tapi saya tidak ingat nama variabel yang akan ditetapkan. Jadi saya Google dan menemukan jawaban ini.
Dino Tw
1
Bagi siapa pun yang memiliki masalah yang sama di Swift: ScaleAspectFitsekarang menjadi enum UIViewContentMode, jadi Anda akan mengatur imageView.contentMode = UIViewContentMode.ScaleAspectFit. Catat periode.
sudo make install
1
translatesAutoresizingMaskIntoConstraintsseharusnya tidak diatur ke false. Butuh waktu lama sebelum saya menyadari bahwa properti ini mencegah perubahan ukuran
Gerald
401

Saya telah melihat sedikit percakapan tentang jenis skala jadi saya memutuskan untuk mengumpulkan artikel tentang beberapa jenis penskalaan mode konten paling populer .

Gambar yang terkait ada di sini:

masukkan deskripsi gambar di sini

Jacksonkr
sumber
Bagaimana Anda menyelaraskan verticallu ketika AspectFit diatur?
esbenr
@ Esbenr Itu harus terjadi secara otomatis. Anda mungkin dapat menemukan penggantian yang diperlukan, tetapi saat ini saya tidak tahu satu pun: |
Jacksonkr
Saya ingin menggunakan Aspect Fill tetapi saya juga ingin menampilkan gambar lengkap. Maka saya perlu mengubah ukuran 'Area agar sesuai'. Bagaimana saya bisa melakukan ini dengan tata letak otomatis?
lee
@ pergi Ada beberapa opsi tetapi itu benar-benar tergantung pada situasi Anda. Saya telah membuat obrolan SOF sehingga kami dapat mendiskusikan topik Anda dan saya akan memberi Anda info yang saya inginkan, silakan kunjungi
Jacksonkr
@ Jackson Itu tidak terjadi secara otomatis sama sekali. Itu memilih ketinggian gambar asli sebelum UIImageView skala itu, sehingga ketinggian TIDAK cocok dengan tinggi Aspek Dipasang baru. Jika ada yang tahu cara yang bagus untuk melakukan ini, beri tahu saya.
datWooWoo
78

Saya baru saja mencoba ini, dan UIImage tidak mendukung _imageScaledToSize.

Saya akhirnya menambahkan metode ke UIImage menggunakan kategori - saran yang saya temukan di forum Apple Dev.

Dalam .h proyek-lebar -

@interface UIImage (Extras)
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
@end;

Penerapan:

@implementation UIImage (Extras)

- (UIImage *)imageByScalingProportionallyToSize:(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;
        else
            scaleFactor = heightFactor;

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


    // this is actually the interesting part:

    UIGraphicsBeginImageContext(targetSize);

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

    [sourceImage drawInRect:thumbnailRect];

    newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

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


    return newImage ;
}

@end;
Jane Sales
sumber
1
alih-alih UIGraphicsBeginImageContext(targetSize);melakukannya jika ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); }mendukung tampilan retina tanpa membuatnya buram
sepeda
38
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
Li-chih Wu
sumber
30

Anda dapat mencoba membuat imageViewukuran sesuai dengan image. Kode berikut tidak diuji.

CGSize kMaxImageViewSize = {.width = 100, .height = 100};
CGSize imageSize = image.size;
CGFloat aspectRatio = imageSize.width / imageSize.height;
CGRect frame = imageView.frame;
if (kMaxImageViewSize.width / aspectRatio <= kMaxImageViewSize.height) 
{
    frame.size.width = kMaxImageViewSize.width;
    frame.size.height = frame.size.width / aspectRatio;
} 
else 
{
    frame.size.height = kMaxImageViewSize.height;
    frame.size.width = frame.size.height * aspectRatio;
}
imageView.frame = frame;
Chris Lundie
sumber
1
pengaturan imageView.frame = XXXX (apa saja) tidak ada bedanya dengan output. ada yang tahu kenapa?
sramij
1
@sramij Jika Anda menggunakan autolayout, pastikan untuk mengacaukan [setTranslatesAutoResize ...] di UIViews. Jika Anda tidak tahu apa artinya memeriksa dokumentasi! :)
datWooWoo
13

seseorang dapat mengubah ukuran UIImage dengan cara ini

image = [UIImage imageWithCGImage:[image CGImage] scale:2.0 orientation:UIImageOrientationUp];
neoneye
sumber
13
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://farm4.static.flickr.com/3092/2915896504_a88b69c9de.jpg"]]];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 


//set contentMode to scale aspect to fit
imageView.contentMode = UIViewContentModeScaleAspectFit;

//change width of frame
//CGRect frame = imageView.frame;
//frame.size.width = 100;
//imageView.frame = frame;

//original lines that deal with frame commented out, yo.
imageView.frame = CGRectMake(10, 20, 60, 60);

...

//Add image view
[myView addSubview:imageView]; 

Kode asli yang diposting di atas berfungsi baik untuk saya di iOS 4.2.

Saya menemukan bahwa membuat CGRect dan menentukan semua nilai atas, kiri, lebar, dan tinggi adalah cara termudah untuk menyesuaikan posisi dalam kasus saya, yang menggunakan UIImageView di dalam sel tabel. (Masih perlu menambahkan kode untuk melepaskan objek)

Nate Flink
sumber
13

Setel ImageView Anda dengan memilih Mode ke Aspect Fill dan centang Clip Subviewskotak.

masukkan deskripsi gambar di sini

Jeffrey Neo
sumber
10

Ini berfungsi dengan baik untuk saya Swift 2.x:

imageView.contentMode = .ScaleAspectFill
imageView.clipsToBounds = true;
vvamondes
sumber
9

Tetapkan UIimageviewskala Anda .........

masukkan deskripsi gambar di sini

PJRadadiya
sumber
6

Untuk Swift:

self.imageViews.contentMode = UIViewContentMode.ScaleToFill
Somir Saikia
sumber
5

UIImageView + Scale.h:

#import <Foundation/Foundation.h>

@interface UIImageView (Scale)

-(void) scaleAspectFit:(CGFloat) scaleFactor;

@end

UIImageView + Scale.m:

#import "UIImageView+Scale.h"

@implementation UIImageView (Scale)


-(void) scaleAspectFit:(CGFloat) scaleFactor{

    self.contentScaleFactor = scaleFactor;
    self.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor);

    CGRect newRect = self.frame;
    newRect.origin.x = 0;
    newRect.origin.y = 0;
    self.frame = newRect;
}

@end
Peter Kreinz
sumber
2

Saya menggunakan kode berikut ini. Di mana imageCoverView berada, UIView menampung UIImageView

if (image.size.height<self.imageCoverView.bounds.size.height && image.size.width<self.imageCoverView.bounds.size.width)
{
    [self.profileImageView sizeToFit];
    self.profileImageView.contentMode =UIViewContentModeCenter
}
else
{
    self.profileImageView.contentMode =UIViewContentModeScaleAspectFit;
}
Avijit Nagare
sumber
2

Jika solusi yang diusulkan di sini tidak bekerja untuk Anda, dan aset gambar Anda sebenarnya adalah PDF, perhatikan bahwa XCode sebenarnya memperlakukan PDF secara berbeda dari file gambar. Secara khusus, tampaknya tidak dapat mengukur untuk mengisi dengan benar dengan PDF: itu malah berakhir dengan ubin. Ini membuat saya gila sampai saya menemukan bahwa masalahnya adalah format PDF. Konversikan ke JPG dan Anda harus siap.

Lane Rettig
sumber
1

Biasanya saya menggunakan metode ini untuk aplikasi saya ( kompatibel Swift 2.x ):

// Resize UIImage
func resizeImage(image:UIImage, scaleX:CGFloat,scaleY:CGFloat) ->UIImage {
    let size = CGSizeApplyAffineTransform(image.size, CGAffineTransformMakeScale(scaleX, scaleY))
    let hasAlpha = true
    let scale: CGFloat = 0.0 // Automatically use scale factor of main screen

    UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
    image.drawInRect(CGRect(origin: CGPointZero, size: size))

    let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return scaledImage
}
Alessandro Ornano
sumber
0

Saya pikir Anda dapat melakukan sesuatu seperti

image.center = [[imageView window] center];
pengguna26359
sumber
3
Ini tidak akan skala gambar tetapi hanya tengah itu.
David Salzer
-3

Inilah cara Anda dapat menskalakannya dengan mudah.

Ini berfungsi dalam 2.x dengan Simulator dan iPhone.

UIImage *thumbnail = [originalImage _imageScaledToSize:CGSizeMake(40.0, 40.0) interpolationQuality:1];
kdbdallas
sumber
hai, apakah Anda tahu apa interpolationQuality: parameter tidak? terima kasih
user102008
27
Ini adalah metode tidak berdokumen (garis bawah adalah hadiah mati) yang dapat mengakibatkan penolakan aplikasi.
Shaggy Frog
Apa yang dilakukan parameter interpolationQuality?
LostInTransit