วิธีปรับขนาด UIImageView ให้เป็นสัดส่วนได้อย่างไร


341

ฉันมี UIImageView และมีวัตถุประสงค์เพื่อลดขนาดตามสัดส่วนโดยให้ความสูงหรือความกว้าง

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;

ภาพได้รับการปรับขนาด แต่ตำแหน่งไม่ได้อยู่ที่มุมบนซ้าย วิธีที่ดีที่สุดในการปรับขนาดภาพ / imageView คืออะไรและฉันจะแก้ไขตำแหน่งได้อย่างไร


ฉันมีบางอย่างที่คล้ายกับรหัสของคุณที่ใช้งานไม่ได้สำหรับฉัน "UIImage * image = [UIImage imageNamed: imageString]; UIImageView * imageView = [[UIImage จัดสรร] initWithImage: image];" trows exeption ที่ฆ่า app ของฉันเล็กน้อยนี้ "แอปยกเลิกเนื่องจากการยกเว้น uncaught 'NSInvalidArgumentException' เหตุผล '- [UIImage initWithImage:]: เลือกไม่รู้จักส่งไปเช่น 0xd815930'"
Spire

3
@Spire มันคือ UIImageView ไม่ใช่ UIImage ^^
Thomas Decaux

2
มันใช้งานได้สำหรับฉัน อย่าลืมตั้งค่า. contentMode เป็น UIImageView ของคุณไม่ใช่ UIImage ของคุณ - นี่คือของฉัน: UIImageView * imageView = [[UIImageView alloc] initWithFrame: CGRectMake (0,0,30,30)]
Jarrett Barnett

คำตอบ:


541

แก้ไขได้ง่ายเมื่อฉันพบเอกสาร!

 imageView.contentMode = UIViewContentModeScaleAspectFit;

19
คุณตอบอะไรจริงๆ ในคำถามของ Ronnie เขากล่าวว่าเขาใช้มัน
Dejell

3
imageView ของคุณอาจไม่ถูกตัด ลองใช้ imageView.layer.masksToBounds = YES;
mackworth

ฉันลองใช้ IB เป็นครั้งแรกเพื่อให้แน่ใจว่าใช้งานได้ตามที่ต้องการ แต่ฉันจำชื่อตัวแปรไม่ได้ ดังนั้นฉัน Google มันและพบคำตอบนี้
Dino Tw

1
สำหรับทุกคนที่มีปัญหาเดียวกันในสวิฟท์: ScaleAspectFitคือตอนนี้เพื่อให้คุณจะตั้งenum UIViewContentMode imageView.contentMode = UIViewContentMode.ScaleAspectFitหมายเหตุช่วงเวลา
sudo ทำการติดตั้ง

1
translatesAutoresizingMaskIntoConstraintsfalseไม่ควรจะกำหนดให้ เอาฉันมานานก่อนที่จะรู้ตัวว่าคุณสมบัตินี้ป้องกันการปรับขนาด
เจอราลด์

401

ผมเคยเห็นบิตของการสนทนาเกี่ยวกับประเภทขนาดดังนั้นผมจึงตัดสินใจที่จะใส่กันบทความเกี่ยวกับบางส่วนของเนื้อหาที่นิยมมากที่สุดประเภทโหมดปรับ

ภาพที่เกี่ยวข้องอยู่ที่นี่:

ป้อนคำอธิบายรูปภาพที่นี่


คุณวางแนวตั้งเมื่อ AspectFit ถูกตั้งค่าอย่างไร
esbenr

@ esbenr ที่ควรเกิดขึ้นโดยอัตโนมัติ คุณอาจสามารถค้นหาการแทนที่ได้ตามต้องการ แต่ตอนนี้ฉันยังไม่รู้จัก
Jacksonkr

ฉันต้องการใช้ Aspect Fill แต่ฉันต้องการแสดงภาพเต็มด้วย จากนั้นฉันต้องเปลี่ยนขนาด 'พื้นที่ให้พอดี' ฉันจะทำสิ่งนี้กับเค้าโครงอัตโนมัติได้อย่างไร
ลี

@lee มีหลายตัวเลือก แต่ขึ้นอยู่กับสถานการณ์ของคุณ ฉันได้สร้างการแชท SOF เพื่อให้เราสามารถพูดคุยเกี่ยวกับหัวข้อของคุณและฉันจะให้ข้อมูลที่คุณต้องการได้โปรดไปที่ถ้าคุณชอบ: chat.stackoverflow.com/rooms/81180/ios-autoresize-chat
Jacksonkr

@ แจ็คสันนั่นไม่ได้เกิดขึ้นโดยอัตโนมัติเลย มันเลือกความสูงของภาพต้นฉบับก่อนที่ UIImageView จะปรับขนาดดังนั้นความสูงจะไม่ตรงกับความสูงของ Aspect Fitted ใหม่ หากใครคิดวิธีที่ดีในการทำเช่นนี้โปรดแจ้งให้เราทราบ
datWooWoo

78

ฉันเพิ่งลองสิ่งนี้และ UIImage ไม่รองรับ _imageScaledToSize

ฉันสิ้นสุดการเพิ่มวิธีใน UIImage โดยใช้หมวดหมู่ - คำแนะนำที่ฉันพบในฟอรัม Apple Dev

ในโครงการกว้าง. h -

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

การดำเนินงาน:

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

1
แทนที่จะUIGraphicsBeginImageContext(targetSize);ทำ([UIScreen instancesRespondToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(targetSize, NO, 0.0f); } else { UIGraphicsBeginImageContext(targetSize); }เพื่อสนับสนุนจอแสดงผลเรตินาโดยไม่ทำให้ตาพร่า
จักรยาน


30

คุณอาจจะลองทำขนาดตรงกับimageView imageรหัสต่อไปนี้ไม่ถูกทดสอบ

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;

1
การตั้งค่า imageView.frame = XXXX (อะไรก็ได้) ไม่ได้ทำให้อะไรแตกต่างออกไป คิดอะไรทำไม
sramij

1
@sramij หากคุณใช้การชำระอัตโนมัติให้ตรวจสอบให้แน่ใจว่าได้ทำกับ [setTranslatesAutoResize ... ] ใน UIViews ถ้าคุณไม่รู้ว่าจะตรวจสอบเอกสารอะไร! :)
datWooWoo

13

หนึ่งสามารถปรับขนาด UIImage ด้วยวิธีนี้

image = [UIImage imageWithCGImage:[image CGImage] scale:2.0 orientation:UIImageOrientationUp];

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

รหัสเดิมที่โพสต์ที่ด้านบนทำงานได้ดีสำหรับฉันใน iOS 4.2

ฉันพบว่าการสร้าง CGRect และระบุค่าสูงสุด, ซ้าย, ความกว้างและความสูงทั้งหมดเป็นวิธีที่ง่ายที่สุดในการปรับตำแหน่งในกรณีของฉันซึ่งใช้ UIImageView ภายในเซลล์ตาราง (ยังต้องเพิ่มรหัสเพื่อปล่อยวัตถุ)


13

ตั้งค่า ImageView ของคุณโดยเลือกโหมดเป็นAspect FillและทำClip Subviewsเครื่องหมายที่กล่อง

ป้อนคำอธิบายรูปภาพที่นี่





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

2

ฉันใช้ code.where ต่อไปนี้ imageCoverView คือ UIView ถือ 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;
}

2

หากโซลูชันที่เสนอในที่นี้ใช้ไม่ได้กับคุณและสินทรัพย์รูปภาพของคุณเป็น PDF จริงโปรดทราบว่า XCode ให้บริการ PDF ที่แตกต่างจากไฟล์รูปภาพ โดยเฉพาะอย่างยิ่งดูเหมือนว่าจะไม่สามารถปรับขนาดให้เหมาะสมกับ PDF ได้: มันจะกลายเป็นกระเบื้องแทน สิ่งนี้ทำให้ฉันเป็นบ้าจนกระทั่งฉันคิดว่าปัญหานี้เป็นรูปแบบ PDF แปลงเป็น JPG และคุณน่าจะดี


1

ปกติฉันจะใช้วิธีนี้สำหรับแอปของฉัน ( ใช้งานร่วมกับ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
}

0

ฉันคิดว่าคุณสามารถทำอะไรบางอย่างเช่น

image.center = [[imageView window] center];

3
มันจะไม่ปรับขนาดของภาพ แต่อยู่ตรงกลาง
David Salzer

-3

นี่คือวิธีที่คุณสามารถปรับขนาดได้อย่างง่ายดาย

ใช้งานได้ใน 2.x กับ Simulator และ iPhone

UIImage *thumbnail = [originalImage _imageScaledToSize:CGSizeMake(40.0, 40.0) interpolationQuality:1];

สวัสดีคุณรู้หรือไม่ว่าการประมาณค่าคุณภาพ: พารามิเตอร์ทำอะไร ขอบคุณ
user102008

27
นี่เป็นวิธีที่ไม่มีเอกสาร (เครื่องหมายขีดเส้นใต้เป็นของกำนัลที่ตายแล้ว) ซึ่งอาจส่งผลให้เกิดการปฏิเสธแอป
Shaggy Frog

พารามิเตอร์ interpolationQuality ทำอะไร
lostInTransit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.