【问题标题】:How to write text on image in Objective-C (iOS)?如何在 Objective-C (iOS) 中的图像上写文本?
【发布时间】:2011-10-22 23:57:21
【问题描述】:

我想以编程方式制作这样的图像:

我有上面的图片和文字。我应该在图片上写文字吗?

我想把它做成一个完整的.png图片(图片+标签),并将其设置为按钮的背景。

【问题讨论】:

  • 你试过 UIImage 和 UILabel 吗?
  • no.. 请提供示例代码以便我尝试。
  • 您只是想在您的应用程序中显示它,还是想编辑图像文件以包含此文本并保存它?
  • 我想把它做成一个完整的图片(图片+标签)并添加到按钮的背景中。

标签: ios iphone uiimageview


【解决方案1】:

在图像内绘制文本并返回结果图像:

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

我使用文本大小来计算纯色矩形的原点,但您可以将其替换为任意数字。

【讨论】:

  • 是的,这就是我需要的东西。但它是在图像的右侧添加文本。我们可以将它添加到图像的底部吗?请帮助
  • 谢谢兄弟。它完美地工作。最后一件事要问,如何设置该文本的背景,如我在示例图片中展示的那样
  • 我收到错误消息:“ImageUtils”未在此范围内声明。这是什么 ImageUtils。请告诉我。我需要和你的要求一样。 @sanchitsingh
  • ImageUtils 是定义了 drawText 方法的类名。做一件事。在您的 .h 文件中声明绘制文本方法并将其定义在 .m 文件中并将其用作 [self drawText:@"Some text" inImage:img atPoint:CGPointMake(0, 0)]; @sachi
  • 它改变了 UIImage 对象,但如果你想要另一个只是做 newImage = [UIImage imageNamed:@"..."];由于底层图像文件被缓存,它不会影响内存或性能。
【解决方案2】:

我对 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 以处理屏幕比例。感谢@SoftDesigner

【讨论】:

  • 谢谢...我需要将颜色移动到 att 字典中才能在 iOS7 中工作: NSDictionary *att = @{ NSFontAttributeName: font, NSForegroundColorAttributeName: [UIColor whiteColor]};
  • 将第一行替换为此以获得更高的文本质量:UIGraphicsBeginImageContextWithOptions(image.size, YES, 0.0f);
  • 不是 UIGraphicsBeginImageContext,而是 UIGraphicsBeginImageContextWithOptions
【解决方案3】:

这是 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 - Drawing text with drawInRect:withAttributes:

How to write text on image in Objective-C (iOS)?

最初的目标是创建一个可以在 AnnotaionView 中使用的动态图像,例如在地图上的给定位置标出价格,这非常适合它。希望这对尝试做同样事情的人有所帮助。

【讨论】:

  • Swift 的绝佳解决方案。非常感谢!
【解决方案4】:

仅限 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"];

【讨论】:

  • 使用 UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0f);以保持图像质量。
  • @SebastianDwornik 0.0f 参数导致代码取决于设备是否为视网膜。
  • 正确。因此,我决定只使用 iOS 7 和 Retina 设备。
  • @neoneye 你能帮我吗?我想在图像上用白色书写文字,并且图像上书写文字的背景区域应该是黑色透明 alpha=0.5 谢谢。
  • @KhalidUsman 是您想要的文本周围半透明的细轮廓吗?
【解决方案5】:

我做了这样的事情!浏览并结合一些示例后。

将文本放在图像的中间,如果需要调整字体大小。

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();

【讨论】:

  • 你为什么要分配一个 UITextView?据我所知,您实际上并没有使用它——您只使用了框架(CGRect)和字体(UIFont),这两者分开保存会更容易。
  • ...啊,除非是 UITextView 正在调整字体大小以适应。
【解决方案6】:

我已经为 UIImage 创建了完全自定义的扩展来在 Swift 中绘制水印:

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】:

这是一个 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

}

【讨论】:

    【解决方案8】:

    使用此方法将您的文本字段添加到具有选定字体、颜色和大小的图像上

    //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; 
    }
    

    【讨论】:

      【解决方案9】:

      在@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!
          }
      

      【讨论】:

        【解决方案10】:

        斯威夫特 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
        
            }
        }
        

        【讨论】:

          【解决方案11】:

          Swift 3 版本的@Hossam Ghareebs 答案 并添加了 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
              }
          }
          

          【讨论】:

            【解决方案12】:

            我的功能可以在图像上添加文字水印,旋转 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)
            

            希望这会有所帮助!!!

            【讨论】:

              【解决方案13】:

              考虑到性能,您应该避免频繁调用-drawRect:。每个UIView 都以CALayer 为后盾,只要CALayer 保留在层次结构中,图像作为图层内容就会保留在内存中。这意味着您在应用程序中看到的大多数操作,包括移动、旋转和视图/图层的缩放,不需要重绘。这意味着您可以在UIImageView 上添加CATextLayer,如果您不需要带水印的图像。 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];
              }
              

              【讨论】:

                【解决方案14】:

                我根据@harish-pathak 提供的示例构建了一个解决方案。它考虑了具有 HiDPI 显示的设备(size 是 int,而 lefttop 是百分比为 double)。

                -(UIImage *)drawText:(NSString *)text onImage:(UIImage *)image withSize:(NSInteger)size posLeft:(double)left posTop:(double)top {
                    
                    // Get UI scale for HiDPI
                    CGFloat scale = [[UIScreen mainScreen] scale];
                    
                    UIColor *textColor = [UIColor whiteColor];
                    UIFont *font = [UIFont fontWithName:@"Font-Name" size:size];
                    
                    // 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
                    UIGraphicsBeginImageContextWithOptions(textSize, NO, scale);
                    
                    // 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);
                    
                    // Create bitmap context for text
                    CGFloat scaledTextWidth = textSize.width * scale;
                    CGFloat scaledTextHeight = textSize.height * scale;
                    CGContextRef textBitmap = CGBitmapContextCreate(NULL, scaledTextWidth, scaledTextHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
                    
                    // Scale text for HiDPI devices
                    CGContextScaleCTM(textBitmap, scale, scale);
                    
                    // Draw image for text
                    CGRect textPosition = CGRectMake(0, 0, textSize.width, textSize.height);
                    CGRect textPixelAligned = CGRectIntegral(textPosition);
                    CGContextDrawImage(textBitmap, textPixelAligned, imageRef);
                    CGImageRef ref = CGBitmapContextCreateImage(textBitmap);
                    UIImage* newImage = [UIImage imageWithCGImage:ref];
                    
                    // Create bitmap context into which the image will be rendered
                    UIGraphicsBeginImageContextWithOptions(imageSize, NO, scale);
                
                    // Use existing opacity as is
                    [image drawInRect:CGRectMake(0,0,imageSize.width,imageSize.height)];
                    
                    // Create new image with blendmode "normal"
                    CGFloat textLeft = (imageSize.width*left)-(textSize.width*0.5);
                    CGFloat textTop = (imageSize.height*top)-(textSize.height*0.5);
                    CGRect imagePosition = CGRectMake(textLeft,textTop,textSize.width,textSize.height);
                    CGRect imagePixelAligned = CGRectIntegral(imagePosition);
                    [newImage drawInRect:imagePixelAligned blendMode:kCGBlendModeNormal alpha:1.0];
                    
                    // Get merged image from context
                    UIImage *mergedImage = UIGraphicsGetImageFromCurrentImageContext();
                
                    UIGraphicsEndImageContext();
                    return mergedImage;
                }
                

                要在图像上居中文本调用函数,如下所示:

                [self drawText:@"Text" onImage:img withSize:120 posLeft:0.5 posTop:0.5];
                

                归功于:

                【讨论】:

                  【解决方案15】:
                  UIImageView *imageView = [UIImageView alloc];
                  imageView.image = [UIImage imageNamed:@"img.png"];
                  UILabel *label = [UILabel alloc];
                  label.text = @"Your text";
                  [imageView addsubview:label];
                  

                  设置要显示标签的标签框架。

                  【讨论】:

                  • 添加为子视图后不要忘记释放标签。
                  • 我想把它做成一个完整的图片(图片+标签)并添加到按钮的背景中。
                  • 在这种情况下,您可能希望在 gimp/photoshop 中创建图像和标签,并将其用作按钮的背景图像。
                  • 其他方法是在图像视图的顶部放置一个清晰的颜色按钮。它会给人同样的印象。
                  • 问题是图片上的文字,而不是 imageView。
                  猜你喜欢
                  • 2011-10-13
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-12-25
                  • 1970-01-01
                  • 2012-07-21
                  • 1970-01-01
                  相关资源
                  最近更新 更多