iPhoneで色付きの1x1 UIImageを動的に作成する方法は?


120

UIColorに基づいて動的に1x1 UIImageを作成したいと思います。

これはQuartz2dですぐに実行できると思います。そして、基礎を理解しようとするドキュメントを調べています。ただし、潜在的な落とし穴がたくさんあるようです。物ごとのビット数とバイト数を正しく識別していない、正しいフラグを指定していない、未使用のデータを解放していない、などです。

Quartz 2d(または別の簡単な方法)でこれを安全に行うにはどうすればよいですか?

回答:


331

あなたは使用することができますCGContextSetFillColorWithColorし、CGContextFillRectこのために:

迅速

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
いいね:-)このメソッドをクラスメソッドとしてカテゴリに入れることをお勧めします。その後、プロジェクトに簡単に追加して、のような行を使用して呼び出すことができます[UIImage imageWithColor: [UIColor redColor]]

7
ループでこれらの画像を作成する場合、または大きなサイズを使用する場合、最適化は、色にアルファがある場合にのみ不透明なキャンバスを使用することです。このように:const CGFloat alpha = CGColorGetAlpha(color.CGColor); const BOOL opaque = alpha == 1; UIGraphicsBeginImageContextWithOptions(size, opaque, 0);
hpique

迅速なバージョンを提供してください
fnc12 2015年

代わりに迅速なものをカスタム初期化子にする方法はありますか?
Antzi

1
なぜUIGraphicsGetCurrentContext()returninなのnilですか?編集:私はそれを得た、私が渡した0ためrectwidth
Iulian Onofrei 2015

9

マットスティーブンのコードに基づく別のオプションを次に示します。サイズ変更可能な無地のカラー画像を作成して、再利用したり、サイズを変更したりできます(たとえば、背景に使用できます)。

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

それをUIImageカテゴリに入れ、接頭辞を変更します。


6

私はマットスティーブンの回答を何度も使用したので、カテゴリを作成しました。

@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

Appleの最新のUIGraphicsImageRendererを使用すると、コードはかなり小さくなります。

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

私にとって、Swiftの便利なinitはすっきりしています。

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

OK、これはあなたが望むものではありませんが、このコードは線を引きます。ポイントを作るためにそれを適応させることができます。または、少なくともそれから少しの情報を取得します。

画像を1x1にするのは少し奇妙に思えます。ストロークは線に乗るので、幅1.0のストロークで0.5が機能します。遊んでみてください。

- (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();
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.