Bagaimana cara membuat gambar UII 1x1 berwarna pada iPhone secara dinamis?


120

Saya ingin membuat gambar UII 1x1 secara dinamis berdasarkan UIColor.

Saya menduga ini dapat dengan cepat dilakukan dengan Quartz2d, ​​dan saya mempelajari dokumentasi mencoba untuk memahami fundamentalnya. Namun, sepertinya ada banyak potensi jebakan: tidak mengidentifikasi jumlah bit dan byte per hal dengan benar, tidak menentukan flag yang tepat, tidak merilis data yang tidak digunakan, dll.

Bagaimana ini bisa dilakukan dengan aman dengan Quartz 2d (atau cara lain yang lebih sederhana)?

Jawaban:


331

Anda dapat menggunakan CGContextSetFillColorWithColordan CGContextFillRectuntuk ini:

Cepat

extension UIImage {
    class func image(with color: UIColor) -> UIImage {
        let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        CGContextSetFillColorWithColor(context, color.CGColor)
        CGContextFillRect(context, rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }
}

Swift3

extension UIImage {
    class func image(with color: UIColor) -> UIImage {
        let rect = CGRect(origin: CGPoint(x: 0, y:0), size: CGSize(width: 1, height: 1))
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()!

        context.setFillColor(color.cgColor)
        context.fill(rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }
}

Objective-C

+ (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

19
Bagus :-) Saya akan merekomendasikan untuk memasukkan metode ini ke dalam kategori sebagai metode kelas, kemudian dapat ditambahkan ke dalam proyek secara sederhana, dan dipanggil menggunakan baris seperti [UIImage imageWithColor: [UIColor redColor]].

7
Jika Anda membuat gambar ini dalam satu lingkaran atau menggunakan ukuran yang lebih besar, pengoptimalannya adalah menggunakan kanvas buram hanya jika warnanya memiliki alfa. Seperti ini:const CGFloat alpha = CGColorGetAlpha(color.CGColor); const BOOL opaque = alpha == 1; UIGraphicsBeginImageContextWithOptions(size, opaque, 0);
hpique

berikan versi cepat
fnc12

Adakah cara untuk menjadikan swift sebagai penginisialisasi khusus?
Antzi

1
Mengapa UIGraphicsGetCurrentContext()kembali nil? Sunting : Saya mengerti, saya lulus 0untuk rectitu width.
Iulian Onofrei

9

Berikut opsi lain berdasarkan kode Matt Stephen. Ini menciptakan gambar warna solid yang dapat diubah ukurannya sehingga Anda dapat menggunakannya kembali atau mengubah ukurannya (misalnya menggunakannya untuk latar belakang).

+ (UIImage *)prefix_resizeableImageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 3.0f, 3.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    image = [image resizableImageWithCapInsets:UIEdgeInsetsMake(1, 1, 1, 1)];

    return image;
}

Taruh di kategori UIImage dan ubah awalannya.


6

Saya menggunakan jawaban Matt Steven berkali-kali sehingga membuat kategori untuk itu:

@interface UIImage (mxcl)
+ (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension;
@end

@implementation UIImage (mxcl)
+ (UIImage *)squareImageWithColor:(UIColor *)color dimension:(int)dimension {
    CGRect rect = CGRectMake(0, 0, dimension, dimension);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}
@end

5

Menggunakan UIGraphicsImageRenderer terbaru dari Apple, kodenya cukup kecil:

import UIKit

extension UIImage {
    static func from(color: UIColor) -> UIImage {
        let size = CGSize(width: 1, height: 1)
        return UIGraphicsImageRenderer(size: size).image(actions: { (context) in
            context.cgContext.setFillColor(color.cgColor)
            context.fill(.init(origin: .zero, size: size))
        })
    }
}

0

Bagi saya, kenyamanan di dalamnya terasa lebih rapi di Swift.

extension UIImage {

    convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {

        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContext(rect.size)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }

        context.setFillColor(color.cgColor)
        context.fill(rect)

        guard let image = context.makeImage() else {
            return nil
        }
        UIGraphicsEndImageContext()

        self.init(cgImage: image)
    }

}

-7

Oke, ini tidak akan persis seperti yang Anda inginkan, tetapi kode ini akan menarik garis. Anda dapat mengadaptasinya untuk membuat suatu poin. Atau setidaknya dapatkan sedikit info darinya.

Membuat gambar 1x1 tampak agak aneh. Pukulan naik pada garis, jadi guratan dengan lebar 1,0 pada 0,5 seharusnya berhasil. Main-main saja.

- (void)drawLine{

UIGraphicsBeginImageContext(CGSizeMake(320,300));

CGContextRef ctx = UIGraphicsGetCurrentContext();

float x = 0;
float xEnd = 320;
float y = 300;

CGContextClearRect(ctx, CGRectMake(5, 45, 320, 300));

CGContextSetGrayStrokeColor(ctx, 1.0, 1.0);

CGContextSetLineWidth(ctx, 1);
CGPoint line[2] = { CGPointMake(x,y), CGPointMake(xEnd, y) };

CGContextStrokeLineSegments(ctx, line, 2);

UIImage *theImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.