Làm thế nào tôi có thể lấy một UIImage và cho nó một viền đen?


126

Làm thế nào tôi có thể thiết lập đường viền của một UIImage?


Tình cờ nếu có ai đó nghe thấy bằng một tìm kiếm google (như tôi đã làm) và đang tìm cách thêm đường viền vào UIImageView, hãy tìm câu trả lời của @mclin ở phía dưới. Hoạt động tuyệt vời!
Mahendra Liya

Câu trả lời:


241

Với HĐH> 3.0 bạn có thể làm điều này:

//you need this import
#import <QuartzCore/QuartzCore.h>

[imageView.layer setBorderColor: [[UIColor blackColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];

1
Khi tôi khía cạnh Tạo các hình ảnh trong hình ảnh trên, hình ảnh được xem hoàn hảo nhưng các cạnh của hình ảnh được để trống và điều tương tự xảy ra với phần trên và dưới của hình ảnh khi hình ảnh nằm ngang. Không gian trống trông xấu xí với đường viền được đặt ở đó .. Bạn đã đối mặt với vấn đề này? Nếu có, vui lòng đề xuất một phương pháp để giải quyết vấn đề này
Gặp gỡ

@ Hamutsi imageView.image = myImage;
Kyle Clegg

6
Có bạn có thể. Trường hợp UIImagecó thể được vẽ vào một bối cảnh đồ họa với CoreGraphics.
Mark Adams

Như @rockstar chỉ ra, bạn có thể cần thêm imageView.layer.masksToBound = YES;
Bjorn Roche

Đây liên kết là giải pháp tôi đang tìm kiếm.
GrandSteph

67

Bạn có thể làm điều này bằng cách tạo một hình ảnh mới (cũng được trả lời trong bài đăng khác của bạn về câu hỏi này):

- (UIImage*)imageWithBorderFromImage:(UIImage*)source;
{
  CGSize size = [source size];
  UIGraphicsBeginImageContext(size);
  CGRect rect = CGRectMake(0, 0, size.width, size.height);
  [source drawInRect:rect blendMode:kCGBlendModeNormal alpha:1.0];

  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextSetRGBStrokeColor(context, 1.0, 0.5, 1.0, 1.0); 
  CGContextStrokeRect(context, rect);
  UIImage *testImg =  UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return testImg;
}  

Mã này sẽ tạo ra một đường viền màu hồng xung quanh hình ảnh. Tuy nhiên nếu bạn sẽ chỉ hiển thị đường viền thì hãy sử dụng lớp của UIImageViewvà đặt đường viền của nó.


Làm thế nào để bạn xác định chiều rộng của đường viền bạn muốn?
Patrick

16
CGContextSetLineWidth
Marcus S. Zarra

@ MarcusS.Zarra Tôi nhận ra rằng họ không tồn tại khi câu hỏi này được trả lời, nhưng giải pháp này không xem xét màn hình Retina. Nếu bạn có thể sửa đổi, tôi thực sự rất biết ơn :)
Luke

@lukech Mẫu không cần phải sửa đổi. Chỉ cần tăng chiều rộng đường nếu bạn đang ở trên thiết bị võng mạc.
Marcus S. Zarra

2
Các sizelà 320x480 bất kể có hay không bạn đang ở trên một thiết bị màn hình Retina, vì vậy khi bạn lưu hình ảnh, nó tiết kiệm tại đó độ phân giải 320x480px, không 640x960.
Luke

38
#import <QuartzCore/CALayer.h>


UIImageView *imageView = [UIImageView alloc]init];
imageView.layer.masksToBounds = YES;
imageView.layer.borderColor = [UIColor blackColor].CGColor;
imageView.layer.borderWidth = 1;    

Mã này có thể được sử dụng để thêm UIImageViewđường viền xem.


hoàn hảo! Không cần phải trải qua những rắc rối của CGImage. (Tôi không cần lưu hình ảnh với đường viền). Cảm ơn nhiều!
Septronic

13
imageView_ProfileImage.layer.cornerRadius =10.0f;
imageView_ProfileImage.layer.borderColor = [[UIColor blackColor] CGColor];
imageView_ProfileImage.layer.borderWidth =.4f;
imageView_ProfileImage.layer.masksToBounds = YES;

Hack tuyệt vời, đặc biệt là khi sử dụng bộ nhớ - các câu trả lời khác sẽ mất gấp 2 lần bộ nhớ chỉ để thêm đường viền đó trong giây lát. Mẹo chuyên nghiệp - Nếu bạn đang tìm cách chỉ thêm một đường viền ở một bên, thì bạn cũng có thể thay đổi giới hạn. Câu trả lời chính xác!
judepereira

11

Nếu bạn biết kích thước của hình ảnh của mình, thì việc thêm đường viền vào lớp của UIImageView là giải pháp tốt nhất AFAIK. Nguyên vẹn, bạn có thể chỉ cần đặtFrame hình ảnh của bạn thành x, y, image.size. Thong, image.size.height

Trong trường hợp bạn có ImageView có kích thước cố định với các hình ảnh được tải động đang được thay đổi kích thước (hoặc được thu nhỏ thành AspectFit), thì mục đích của bạn là thay đổi kích thước hình ảnh thành hình ảnh mới được thay đổi kích thước.

Cách ngắn nhất để làm điều này:

// containerView is my UIImageView
containerView.layer.borderWidth = 7;
containerView.layer.borderColor = [UIColor colorWithRed:0.22 green:0.22 blue:0.22 alpha:1.0].CGColor;

// this is the key command
[containerView setFrame:AVMakeRectWithAspectRatioInsideRect(image.size, containerView.frame)];

Nhưng để sử dụng AVMakeRectWithAspectRatioInsideRect, bạn cần thêm cái này

#import <AVFoundation/AVFoundation.h>

nhập câu lệnh vào tệp của bạn và cũng bao gồm khung AVFoundation trong dự án của bạn (đi kèm với SDK).


Cảm ơn @rafinskipg! Nhiều đánh giá cao.
ScorpionKing2k5

8

Bạn không thể thêm đường viền, nhưng điều này sẽ có hiệu quả tương tự. Bạn cũng có thể biến UIView được gọi là blackBG trong ví dụ này thành UIImageView với hình ảnh viền và giữa trống, sau đó bạn sẽ có viền hình ảnh tùy chỉnh thay vì chỉ màu đen.

UIView *blackBG = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];

blackBG.backgroundColor = [UIColor blackColor];

UIImageView *myPicture = [[UIImageView alloc] initWithImage:
                          [UIImage imageNamed: @"myPicture.jpg"]];

int borderWidth = 10;

myPicture.frame = CGRectMake(borderWidth,
                             borderWidth,
                             blackBG.frame.size.width-borderWidth*2,
                             blackBG.frame.size.height-borderWidth*2)];

[blackBG addSubview: myPicture];

Đây là những gì tôi đã làm; lồng tôi UIImageViewvào giữa UIViewmàu khung lớn hơn một chút .
Ben Kreeger

6

tất cả các câu trả lời này hoạt động tốt NHƯNG thêm một chỉnh sửa cho một hình ảnh. Giả sử Bạn có hình dạng (trong trường hợp của tôi là một con bướm) và Bạn muốn thêm một đường viền (đường viền màu đỏ):

chúng ta cần hai bước: 1) chụp ảnh, chuyển đổi sang CGImage, chuyển sang một chức năng để vẽ màn hình trong bối cảnh sử dụng CoreGraphics và trả lại CGImage mới

2) chuyển đổi sang uiimage trở lại và vẽ:

// remember to release object!
+ (CGImageRef)createResizedCGImage:(CGImageRef)image toWidth:(int)width
andHeight:(int)height
{
// create context, keeping original image properties
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, width,
                                             height,
                                             8
                                             4 * width,
                                             colorspace,
                                             kCGImageAlphaPremultipliedFirst
                                             );

 CGColorSpaceRelease(colorspace);

if(context == NULL)
    return nil;

// draw image to context (resizing it)
CGContextSetInterpolationQuality(context, kCGInterpolationDefault);

CGSize offset = CGSizeMake(2,2);
CGFloat blur = 4;   
CGColorRef color = [UIColor redColor].CGColor;
CGContextSetShadowWithColor ( context, offset, blur, color);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
// extract resulting image from context
CGImageRef imgRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
return imgRef;

}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

CGRect frame = CGRectMake(0,0,160, 122);
UIImage * img = [UIImage imageNamed:@"butterfly"]; // take low res OR high res, but frame should be the low-res one.
imgV = [[UIImageView alloc]initWithFrame:frame];
[imgV setImage: img];
imgV.center = self.view.center;
[self.view addSubview: imgV];

frame.size.width = frame.size.width * 1.3;
frame.size.height = frame.size.height* 1.3;
CGImageRef cgImage =[ViewController createResizedCGImage:[img CGImage] toWidth:frame.size.width andHeight: frame.size.height ];

imgV2 = [[UIImageView alloc]initWithFrame:frame];
[imgV2 setImage: [UIImage imageWithCGImage:cgImage] ];

// release:
if (cgImage) CGImageRelease(cgImage);

[self.view addSubview: imgV2];

}

Tôi đã thêm một con bướm bình thường và một con bướm lớn hơn viền đỏ.


Có cách nào để đặt chiều rộng của viền đỏ ở đây không.
coder1010

5

Bạn có thể thêm viền vào UIImageView, sau đó thay đổi kích thước của UIimageView theo kích thước hình ảnh:

#import <QuartzCore/QuartzCore.h>


// adding border to the imageView
[imageView.layer setBorderColor: [[UIColor whiteColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];

// resize the imageView to fit the image size
CGSize size = [image size];
float factor = size.width / self.frame.size.width;
if (factor < size.height / self.frame.size.height) {
    factor = size.height / self.frame.size.height;
}

CGRect rect = CGRectMake(0, 0, size.width/factor, size.height/factor);
imageView.frame = rect;

Đảm bảo bạn đặt nguồn gốc của imageView ở giữa


2

Bạn có thể tự xử lý hình ảnh, nhưng cách tốt hơn nhiều là chỉ cần thêm một UIView có chứa UIImageView và thay đổi nền thành màu đen. Sau đó đặt kích thước của chế độ xem vùng chứa lớn hơn một chút so với UIImageView.


Nó sẽ làm việc với một kích thước khác nhau của hình ảnh thay đổi nhanh chóng? UIImageView sẽ thay đổi mọi lúc, còn UIView? ps Thao tác với hình ảnh chính nó sẽ là tuyệt vời.
Shay

Bạn phải điều chỉnh khung của chế độ xem chứa cùng với hình ảnh - bạn có thể lưu các thuộc tính trung tâm cho cả hai chế độ xem, điều chỉnh kích thước hình ảnh, điều chỉnh kích thước vùng chứa và sau đó đặt lại thuộc tính trung tâm cho cả hai.
Kendall Helmstetter Gelner

Đây chính xác là cách tôi đã làm trái ngược với việc vuốt ve con đường với CG. chỉ có vẻ dễ dàng hơn.
Corey Floyd

2

Một cách khác là làm trực tiếp từ nhà thiết kế.

Chọn hình ảnh của bạn và vào phần "Hiển thị thanh tra danh tính".

Tại đây bạn có thể thêm thủ công " Thuộc tính thời gian chạy do người dùng xác định" :

layer.borderColor
layer.borderWidth


nhập mô tả hình ảnh ở đây


1
Điều này sẽ không hoạt động vì bạn cần CGColor và thông qua XIB, nó chỉ cung cấp UIColor
mã hóa

Màu sắc sẽ không hoạt động, nhưng nếu bạn chỉ cần một màu đen - đây là câu trả lời hiệu quả nhất "dòng mã" = D
soprof

1

// bạn cần nhập

QuartzCore/QuartzCore.h

& sau đó cho ImageView trong viền

[imageView.layer setBorderColor: [[UIColor blackColor] CGColor]];

[imageView.layer setBorderWidth: 2.0];

[imageView.layer setCornerRadius: 5.0];

1

Hàm này sẽ trả về hình ảnh của bạn với viền đen thử điều này .. hy vọng điều này sẽ giúp bạn

- (UIImage *)addBorderToImage:(UIImage *)image frameImage:(UIImage *)blackBorderImage
{
    CGSize size = CGSizeMake(image.size.width,image.size.height);
    UIGraphicsBeginImageContext(size);

    CGPoint thumbPoint = CGPointMake(0,0);

    [image drawAtPoint:thumbPoint];


    UIGraphicsBeginImageContext(size);
    CGImageRef imgRef = blackBorderImage.CGImage;
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width,size.height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGPoint starredPoint = CGPointMake(0, 0);
    [imageCopy drawAtPoint:starredPoint];
    UIImage *imageC = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imageC;
}

Nếu bạn tìm thấy bất kỳ gliches xin vui lòng cho tôi biết ... tôi sẽ cải thiện nó
SachinVsSachin

1

Trong Swift 3 đây là cách bạn làm điều đó với chính UIImage:

let size = CGSize(width: image.size.width, height: image.size.height)
UIGraphicsBeginImageContext(size)
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
image?.draw(in: rect, blendMode: .normal, alpha: 1.0)
let context = UIGraphicsGetCurrentContext()
context?.setStrokeColor(red: 0, green: 0, blue: 0, alpha: 1)
context?.stroke(rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

self.imageView.image = newImage

1

Đối với những người tìm kiếm giải pháp plug-and-play trên UIImage, tôi đã viết câu trả lời của CodyMace dưới dạng phần mở rộng.

Sử dụng: let outlined = UIImage(named: "something")?.outline()

extension UIImage {

    func outline() -> UIImage? {

        let size = CGSize(width: self.size.width, height: self.size.height)
        UIGraphicsBeginImageContext(size)
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        self.draw(in: rect, blendMode: .normal, alpha: 1.0)
        let context = UIGraphicsGetCurrentContext()
        context?.setStrokeColor(red: 0, green: 0, blue: 0, alpha: 1)
        context?.stroke(rect)
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage

    }

}

0

Tôi đã tạo một lớp có thêm đường viền cho imageView h. Sử dụng lớp này thay vì UIImageView.I đã cung cấp phần đệm là 4. Bạn có thể cung cấp theo mong muốn của mình.

class UIBorderImageView: UIView {

private lazy var imageView: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFit
    imageView.translatesAutoresizingMaskIntoConstraints = false
    return imageView
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    self.backgroundColor = UIColor.White()
    self.layer.borderColor = UIColor.GreyMedium().cgColor
    self.layer.borderWidth = 1.0
    self.layer.cornerRadius = 4.0
    self.layer.masksToBounds = true
    self.setUpViews()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

private func setUpViews(){
    self.addSubview(imageView)
    self.addConstraintsWithFormat(format: "H:|-4-[v0]-4-|", views: imageView)
    self.addConstraintsWithFormat(format: "V:|-4-[v0]-4-|", views: imageView)
}

func configureImageViewWith(image:UIImage){
    self.imageview.image = image 
}}

-1

Tôi sử dụng phương pháp này để thêm một đường viền bên ngoài hình ảnh . Bạn có thể tùy chỉnh độ rộng đường viền boderWidthkhông đổi.

Swift 3

func addBorderToImage(image : UIImage) -> UIImage {
    let bgImage = image.cgImage
    let initialWidth = (bgImage?.width)!
    let initialHeight = (bgImage?.height)!
    let borderWidth = Int(Double(initialWidth) * 0.10);
    let width = initialWidth + borderWidth * 2
    let height = initialHeight + borderWidth * 2
    let data = malloc(width * height * 4)

    let context = CGContext(data: data,
                        width: width,
                        height: height,
                        bitsPerComponent: 8,
                        bytesPerRow: width * 4,
                        space: (bgImage?.colorSpace)!,
                        bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue);

    context?.draw(bgImage!, in: CGRect(x: CGFloat(borderWidth), y: CGFloat(borderWidth), width: CGFloat(initialWidth), height: CGFloat(initialHeight)))
    context?.setStrokeColor(UIColor.white.cgColor)
    context?.setLineWidth(CGFloat(borderWidth))
    context?.move(to: CGPoint(x: 0, y: 0))
    context?.addLine(to: CGPoint(x: 0, y: height))
    context?.addLine(to: CGPoint(x: width, y: height))
    context?.addLine(to: CGPoint(x: width, y: 0))
    context?.addLine(to: CGPoint(x: 0, y: 0))
    context?.strokePath()

    let cgImage = context?.makeImage()
    let uiImage = UIImage(cgImage: cgImage!)

    free(data)

    return uiImage;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.