web-dev-qa-db-ja.com

Objective-C(iOS)で画像にテキストを書き込む方法

このようなイメージをプログラムで作成したい:

example

上の画像とテキストがあります。画像にテキストを書くべきですか?

完全な.png画像(画像+ラベル)にして、ボタンの背景として設定します。

75
Sanchit Paurush

画像内にテキストを描画し、結果の画像を返します。

+(UIImage*) drawText:(NSString*) text 
             inImage:(UIImage*)  image 
             atPoint:(CGPoint)   point 
{

    UIFont *font = [UIFont boldSystemFontOfSize:12];
    UIGraphicsBeginImageContext(image.size);
    [image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
    CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
    [[UIColor whiteColor] set];
    [text drawInRect:CGRectIntegral(rect) withFont:font]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return newImage;
}

使用法:

// note: replace "ImageUtils" with the class where you pasted the method above
UIImage *img = [ImageUtils drawText:@"Some text"
                            inImage:img 
                            atPoint:CGPointMake(0, 0)];

画像内のテキストの原点を0,0から任意のポイントに変更します。

テキストの背後に単色の長方形をペイントするには、[[UIColor whiteColor] set];行の前に次を追加します。

[[UIColor brownColor] set];
CGContextFillRect(UIGraphicsGetCurrentContext(), 
                  CGRectMake(0, (image.size.height-[text sizeWithFont:font].height), 
                                  image.size.width, image.size.height));

テキストサイズを使用して、単色の四角形の原点を計算していますが、任意の数値に置き換えることができます。

175
Jano

IOS 7サポートの最初の回答に対する私の貢献:

+(UIImage*) drawText:(NSString*) text
             inImage:(UIImage*)  image
             atPoint:(CGPoint)   point
{
    UIGraphicsBeginImageContextWithOptions(image.size, YES, 0.0f);
    [image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
    CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
    [[UIColor whiteColor] set];

    UIFont *font = [UIFont boldSystemFontOfSize:12];
    if([text respondsToSelector:@selector(drawInRect:withAttributes:)])
    {
        //iOS 7
        NSDictionary *att = @{NSFontAttributeName:font};
        [text drawInRect:rect withAttributes:att];
    }
    else
    {
        //legacy support
        [text drawInRect:CGRectIntegral(rect) withFont:font];
    }

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

    return newImage;
}

お役に立てれば

編集:画面スケールを処理するためにUIGraphicsBeginImageContextWithOptionsを変更しました。 Thk @SoftDesigner

34
iGranDav

Swiftバージョンです。

func textToImage(drawText: NSString, inImage: UIImage, atPoint:CGPoint)->UIImage{

    // Setup the font specific variables
    var textColor: UIColor = UIColor.whiteColor()
    var textFont: UIFont = UIFont(name: "Helvetica Bold", size: 12)!

    //Setup the image context using the passed image.
    UIGraphicsBeginImageContext(inImage.size)

    //Setups up the font attributes that will be later used to dictate how the text should be drawn
    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
    ]

    //Put the image into a rectangle as large as the original image.
    inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height))

    // Creating a point within the space that is as bit as the image.
    var rect: CGRect = CGRectMake(atPoint.x, atPoint.y, inImage.size.width, inImage.size.height)

    //Now Draw the text into an image.
    drawText.drawInRect(rect, withAttributes: textFontAttributes)

    // Create a new image out of the images we have created
    var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()

    // End the context now that we have the image we need
    UIGraphicsEndImageContext()

    //And pass it back up to the caller.
    return newImage

}

呼び出すには、画像を渡すだけです。

textToImage("000", inImage: UIImage(named:"thisImage.png")!, atPoint: CGPointMake(20, 20))

以下のリンクは、私がこれをまっすぐにするのを助けました。

Swift-drawInRect:withAttributes: でテキストを描画

Objective-C(iOS)で画像にテキストを書き込む方法は?

元の目標は、地図上の特定の場所に価格を設定するなど、AnnotaionViewで使用できる動的な画像を作成することでした。これが誰かが同じことをしようとしているのを助けることを願っています。

iOS7のみ。

右下隅の透かし。

@interface UIImage (DrawWatermarkText)
-(UIImage*)drawWatermarkText:(NSString*)text;
@end
@implementation UIImage (DrawWatermarkText)
-(UIImage*)drawWatermarkText:(NSString*)text {
    UIColor *textColor = [UIColor colorWithWhite:0.5 alpha:1.0];
    UIFont *font = [UIFont systemFontOfSize:50];
    CGFloat paddingX = 20.f;
    CGFloat paddingY = 20.f;

    // Compute rect to draw the text inside
    CGSize imageSize = self.size;
    NSDictionary *attr = @{NSForegroundColorAttributeName: textColor, NSFontAttributeName: font};
    CGSize textSize = [text sizeWithAttributes:attr];
    CGRect textRect = CGRectMake(imageSize.width - textSize.width - paddingX, imageSize.height - textSize.height - paddingY, textSize.width, textSize.height);

    // Create the image
    UIGraphicsBeginImageContext(imageSize);
    [self drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
    [text drawInRect:CGRectIntegral(textRect) withAttributes:attr];
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultImage;
}
@end

使用法:

UIImage *image = [UIImage imageNamed:@"mona_Lisa"];
image = [image drawWatermarkText:@"Leonardo da Vinci"];
18
neoneye

私はこのようなことをしました!いくつかの例を参照して組み合わせた後。

テキストを画像の中央に配置し、必要に応じてフォントのサイズを変更します。

UIImage *myImage = [UIImage imageNamed:@"promoicon.png"];
UIGraphicsBeginImageContext(myImage.size);
[myImage drawInRect:CGRectMake(0,0,myImage.size.width,myImage.size.height)];
UITextView *myText = [[UITextView alloc] init];
myText.font = [UIFont fontWithName:@"TrebuchetMS-Bold" size:15.0f];
myText.textColor = [UIColor whiteColor];
myText.text = NSLocalizedString(@"promotionImageText", @"");
myText.backgroundColor = [UIColor clearColor];

CGSize maximumLabelSize = CGSizeMake(myImage.size.width,myImage.size.height);
CGSize expectedLabelSize = [myText.text sizeWithFont:myText.font                     
                                          constrainedToSize:maximumLabelSize 
                                              lineBreakMode:UILineBreakModeWordWrap];

myText.frame = CGRectMake((myImage.size.width / 2) - (expectedLabelSize.width / 2),
                                  (myImage.size.height / 2) - (expectedLabelSize.height / 2),
                                  myImage.size.width,
                                  myImage.size.height);

[[UIColor whiteColor] set];
[myText.text drawInRect:myText.frame withFont:myText.font];
UIImage *myNewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
12
nunoines

Swiftに透かしを描画するために、UIImageの完全にカスタマイズされた拡張機能を作成しました。

extension UIImage{

    enum WaterMarkCorner{
        case TopLeft
        case TopRight
        case BottomLeft
        case BottomRight
    }

    func waterMarkedImage(#waterMarkText:String, corner:WaterMarkCorner = .BottomRight, margin:CGPoint = CGPoint(x: 20, y: 20), waterMarkTextColor:UIColor = UIColor.whiteColor(), waterMarkTextFont:UIFont = UIFont.systemFontOfSize(20), backgroundColor:UIColor = UIColor.clearColor()) -> UIImage{

        let textAttributes = [NSForegroundColorAttributeName:waterMarkTextColor, NSFontAttributeName:waterMarkTextFont]
        let textSize = NSString(string: waterMarkText).sizeWithAttributes(textAttributes)
        var textFrame = CGRectMake(0, 0, textSize.width, textSize.height)

        let imageSize = self.size
        switch corner{
        case .TopLeft:
            textFrame.Origin = margin
        case .TopRight:
            textFrame.Origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y)
        case .BottomLeft:
            textFrame.Origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y)
        case .BottomRight:
            textFrame.Origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y)
        }

        /// Start creating the image with water mark
        UIGraphicsBeginImageContext(imageSize)
        self.drawInRect(CGRectMake(0, 0, imageSize.width, imageSize.height))
        NSString(string: waterMarkText).drawInRect(textFrame, withAttributes: textAttributes)

        let waterMarkedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return waterMarkedImage
    }
}

ご覧のとおり、変更する必要がない場合は無視できるように、属性のデフォルト値をいくつか追加しました。以下に、使用方法の例を示します。

let watermark1 = image.waterMarkedImage(waterMarkText: "@yourapp")

let watermark2 = image.waterMarkedImage(waterMarkText: "your app name", corner: .TopRight, margin: CGPoint(x: 5, y: 5), waterMarkTextColor: UIColor.greenColor())

let watermark3 = image.waterMarkedImage(waterMarkText: "appName", waterMarkTextColor: UIColor.blackColor(), waterMarkTextFont: UIFont(name: "Helvatica", size: 25)!)

Swift 4.0バージョン:

extension UIImage
{

    enum WaterMarkCorner
    {
        case TopLeft
        case TopRight
        case BottomLeft
        case BottomRight
    }

    func waterMarkedImage(text:String, corner:WaterMarkCorner = .BottomRight, margin:CGPoint = CGPoint(x: 20, y: 20), color:UIColor = UIColor.white, font:UIFont = UIFont.systemFont(ofSize: 20), background:UIColor = UIColor.clear) -> UIImage?
    {
        let attributes = [NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.font:font]
        let textSize = NSString(string: text).size(withAttributes: attributes)
        var frame = CGRect(x: 0, y: 0, width: textSize.width, height: textSize.height)

        let imageSize = self.size
        switch corner
        {
            case .TopLeft:
                frame.Origin = margin
            case .TopRight:
                frame.Origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y)
            case .BottomLeft:
                frame.Origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y)
            case .BottomRight:
                frame.Origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y)
        }

        // Start creating the image with water mark
        UIGraphicsBeginImageContext(imageSize)
        self.draw(in: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
        NSString(string: text).draw(in: frame, withAttributes: attributes)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }

}
7
Hossam Ghareeb

以下はSwiftバージョンで、テキストを画像の中央に正しく配置します。これはさまざまなサイズのテキストで機能します。

func addTextToImage(text: NSString, inImage: UIImage, atPoint:CGPoint)     -> UIImage{

    // Setup the font specific variables
    let textColor = YOURCOLOR
    let textFont = YOUR SIZE

    //Setups up the font attributes that will be later used to dictate how the text should be drawn
    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
    ]

    // Create bitmap based graphics context
    UIGraphicsBeginImageContextWithOptions(inImage.size, false, 0.0)

    //Put the image into a rectangle as large as the original image.
    inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height))

    // Our drawing bounds
    let drawingBounds = CGRectMake(0.0, 0.0, inImage.size.width, inImage.size.height)

    let textSize = text.sizeWithAttributes([NSFontAttributeName:textFont])
    let textRect = CGRectMake(drawingBounds.size.width/2 - textSize.width/2, drawingBounds.size.height/2 - textSize.height/2,
        textSize.width, textSize.height)

    text.drawInRect(textRect, withAttributes: textFontAttributes)

    // Get the image from the graphics context
    let newImag = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImag

}
2
superpeteblaze

このメソッドを使用して、選択したフォント、色、サイズで画像にテキストフィールドを追加します

//Method to add 
- (UIImage *) addText:(UIImage *)img text:(NSString *)text
{
    CGRect rect =  CGRectMake(0,0, img.size.width, img.size.height);

    // create a context according to image size
    UIGraphicsBeginImageContext(rect.size);

    // draw image
    [img drawInRect:rect];


    float fontSize = _txtvwEdit.font.pointSize*2;
    NSLog(@"Original %f new %f",_txtvwEdit.font.pointSize,fontSize);

    UIFont* font = [UIFont fontWithName:_txtvwEdit.font.fontName size:fontSize];

    CGRect textRect = CGRectMake((_txtvwEdit.frame.Origin.x*2)-5,_txtvwEdit.frame.Origin.y*2,_txtvwEdit.frame.size.width*2,_txtvwEdit.frame.size.height*2);

    if ([temparyGifframes count]>0)
    {
        font = [UIFont fontWithName:_txtvwEdit.font.fontName size:_txtvwEdit.font.pointSize];

        textRect =    CGRectMake(_txtvwEdit.frame.Origin.x,_txtvwEdit.frame.Origin.y ,_txtvwEdit.frame.size.width,_txtvwEdit.frame.size.height);

    }

    /// Make a copy of the default paragraph style
    NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
    paragraphStyle.alignment = NSTextAlignmentLeft;

    NSDictionary *attributes = @{ NSFontAttributeName: font, NSForegroundColorAttributeName: _txtvwEdit.textColor,NSParagraphStyleAttributeName: paragraphStyle };

    // draw text
    [text drawInRect:textRect withAttributes:attributes];


    // get as image
    UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image; 
}
1
Piyush

@JanoのSwift-3回答:-

func drawText(text:NSString ,image:UIImage ,point:CGPoint ) -> UIImage {

        let font = UIFont.boldSystemFont(ofSize: 12)
        UIGraphicsBeginImageContext(image.size)
        image.draw(in:CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) )
            let rect = CGRect(x: point.x, y: point.y, width:image.size.width, height: image.size.height )
        UIColor.white.set()
        text.draw(in: rect.integral, withAttributes: [NSFontAttributeName   : font])
        let image =  UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
0
Shrawan

私の機能は、45度と90度の回転で画像にテキストウォーターマークを追加できます

+(UIImage *)drawText:(NSString *)text diagonallyOnImage:(UIImage *)image rotation:(WatermarkRotation)rotation{

    UIColor *textColor = [UIColor colorWithRed:255 green:0 blue:0 alpha:0.2];//[UIColor colorWithWhite:0.5 alpha:1.0];
    UIFont *font = [UIFont systemFontOfSize:250];

    // Compute rect to draw the text inside
    NSDictionary *attr = @{NSForegroundColorAttributeName: textColor, NSFontAttributeName: font};
    CGSize textSize = [text sizeWithAttributes:attr];
    CGSize imageSize = image.size;
    // Create a bitmap context into which the text will be rendered.
    UIGraphicsBeginImageContext(textSize);
    // Render the text
    [text drawAtPoint:CGPointMake(0,0) withAttributes:attr];
    // Retrieve the image
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext();

    CGImageRef imageRef = [img CGImage];
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);


    CGContextRef bitmap = CGBitmapContextCreate(NULL, textSize.width, textSize.width, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

    switch (rotation) {
        case WatermarkRotation90left:
            CGContextRotateCTM (bitmap, DEGREES_RADIANS(-90));
            CGContextTranslateCTM(bitmap, -textSize.width, 0);
            break;

        case WatermarkRotation90right:
            CGContextRotateCTM (bitmap, DEGREES_RADIANS(90));
            CGContextTranslateCTM(bitmap, 0, -textSize.width);
            break;

        case WatermarkRotation45ltr:
            CGContextRotateCTM (bitmap, DEGREES_RADIANS(45));
            CGContextTranslateCTM(bitmap, textSize.width/4, -textSize.width/2);
            break;

        case WatermarkRotation45rtl:
            CGContextRotateCTM (bitmap, DEGREES_RADIANS(-45));
            CGContextTranslateCTM(bitmap, -textSize.width/2, textSize.width/4);
            break;

        default:
            break;
    }

    CGContextDrawImage(bitmap, CGRectMake(0, (textSize.width/2)-(textSize.height/2), textSize.width, textSize.height), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage* newImage = [UIImage imageWithCGImage:ref];

    UIGraphicsBeginImageContext( imageSize );

    // Use existing opacity as is
    [image drawInRect:CGRectMake(0,0,imageSize.width,imageSize.height)];


    if (rotation == WatermarkRotation90left) {
        [newImage drawInRect:CGRectMake(-((textSize.width/2)-(textSize.height/2)),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0];
    }else if(rotation == WatermarkRotation90right){
        [newImage drawInRect:CGRectMake((imageSize.width-textSize.width/2)-(textSize.height/2),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0];
    }else{
        [newImage drawInRect:CGRectMake((imageSize.width/2)-(textSize.width/2),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0];
    }


    UIImage *mergedImage = UIGraphicsGetImageFromCurrentImageContext();


    UIGraphicsEndImageContext();
    return mergedImage;
}

回転の列挙:

typedef enum:NSUInteger{
    WatermarkRotation90left=1,
    WatermarkRotation90right,
    WatermarkRotation45ltr,
    WatermarkRotation45rtl
}WatermarkRotation;

注:画像の中心に透かしを描くには0を使用します(switchステートメントのデフォルトの場合)。

次のマクロを度からラジアンに追加します。

#define DEGREES_RADIANS(angle) ((angle) / 180.0 * M_PI)

お役に立てれば !!!

0
Harish Pathak

パフォーマンスを考慮すると、-drawRect:を頻繁に呼び出すことは避けてください。すべてのUIViewCALayerでバックアップされ、CALayerが階層内にある限り、レイヤーのコンテンツはメモリに残ります。これは、ビュー/レイヤーの移動、回転、スケーリングを含むアプリケーションは、再描画を必要としません。これは、CATextLayerUIImageViewを追加して使用できることを意味します。透かし入りの画像。 https://developer.Apple.com/library/ios/qa/qa1708/_index.html

    CATextLayer *textLayer = [CATextLayer layer];
    UIFont *font = [UIFont systemFontOfSize:14.0f];
    CGSize textSize = [text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14.0f]}];
    textLayer.frame = CGRectMake((imageView.size.width - textSize.width)/2,
                                 (imageView.size.height - textSize.height)/2,
                                 textSize.width, textSize.height);;
    textLayer.string = text;
    textLayer.fontSize = font.pointSize;
    [imageView.layer addSublayer:textLayer];
}
0
RongyanZheng

@Hossam GhareebsのSwift 3バージョンは答え、不足しているbackgroundColorパラメーターの統合を追加しました:

enum WaterMarkCorner{
    case TopLeft
    case TopRight
    case BottomLeft
    case BottomRight
}

extension UIImage{

    func waterMarkedImage(_ waterMarkText:String, corner:WaterMarkCorner = .TopRight, margin:CGPoint = CGPoint(x: 20, y: 20), waterMarkTextColor:UIColor = UIColor.black, waterMarkTextFont:UIFont = UIFont.systemFont(ofSize: 40), backgroundColor:UIColor = UIColor(white: 1.0, alpha: 0.5)) -> UIImage?{

        let textAttributes = [NSForegroundColorAttributeName:waterMarkTextColor, NSFontAttributeName:waterMarkTextFont, NSBackgroundColorAttributeName: backgroundColor]
        let textSize = NSString(string: waterMarkText).size(attributes: textAttributes)
        var textFrame = CGRect(x:0, y:0, width:textSize.width, height:textSize.height)

        let imageSize = self.size
        switch corner{
        case .TopLeft:
            textFrame.Origin = margin
        case .TopRight:
            textFrame.Origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y)
        case .BottomLeft:
            textFrame.Origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y)
        case .BottomRight:
            textFrame.Origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y)
        }

        /// Start creating the image with water mark
        UIGraphicsBeginImageContext(imageSize)
        self.draw(in: CGRect(x:0, y:0, width:imageSize.width, height:imageSize.height))

        NSString(string: waterMarkText).draw(in: textFrame, withAttributes: textAttributes)

        let waterMarkedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return waterMarkedImage
    }
}
0

スイフト3

extension UIImage {

    func textToImage(drawText: NSString, atPoint:CGPoint) -> UIImage? {

        // Setup the font specific variables
        let textColor: UIColor = UIColor.white
        let textFont: UIFont = UIFont(name: "Helvetica Bold", size: 12)!

        //Setup the image context using the passed image.
        UIGraphicsBeginImageContext(self.size)

        //Setups up the font attributes that will be later used to dictate how the text should be drawn
        let textFontAttributes = [
            NSFontAttributeName: textFont,
            NSForegroundColorAttributeName: textColor,
            ] as [String : Any]

        //Put the image into a rectangle as large as the original image.
        self.draw(in: CGRect(x:0, y:0, width:self.size.width, height: self.size.height))

        // Creating a point within the space that is as bit as the image.
        let rect: CGRect = CGRect(x:atPoint.x, y:atPoint.y, width:self.size.width, height:self.size.height)

        //Now Draw the text into an image.
        drawText.draw(in: rect, withAttributes: textFontAttributes)

        // Create a new image out of the images we have created
        let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()

        // End the context now that we have the image we need
        UIGraphicsEndImageContext()

        //And pass it back up to the caller.
        return newImage

    }
}
0
johnnyMac