草庐IT

ios - 在图片右上角绘制文字

coder 2023-09-10 原文

我想在 UIImage 的右上角或右下角绘制文本。 我有一个非常适合绘制文本的扩展,但问题是将文本定位在屏幕右侧(因为文本被剪切)。

这是扩展:

extension UIImage {

func addText(drawText: NSString, atPoint: CGPoint, textColor: UIColor?, textFont: UIFont?) -> UIImage{

    // Setup the font specific variables
    var _textColor: UIColor
    if textColor == nil {
        _textColor = UIColor.white
    } else {
        _textColor = textColor!
    }

    var _textFont: UIFont
    if textFont == nil {
        _textFont = UIFont.systemFont(ofSize: 50)
    } else {
        _textFont = textFont!
    }

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

    // Setup 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
    draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))

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


    // 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 = UIGraphicsGetImageFromCurrentImageContext()

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

    //Pass the image back up to the caller
    return newImage!
}
}

问题是如果文本太长或太大,它就会超出屏幕。我需要更改原点以从右向左书写文本,这样它只会在屏幕左侧占用空间,而不会在屏幕右侧占用空间。我该怎么做?

最佳答案

有一个简单的函数调用来获取字符串的“边界框”。您可以使用它来定位文本应该绘制到图像中的位置:

    // get the bounding-box for the string
    let stringSize = drawText.size(attributes: textFontAttributes)

    // position the bounding-box at the bottom-right corner of the image
    let x = self.size.width - ceil(stringSize.width)
    let y = self.size.height - ceil(stringSize.height)

    let rect = CGRect(x: x, y: y, width: stringSize.width, height: stringSize.height)

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

请注意,此示例代码将文本定位在右下角 - 忽略 atPoint 参数。您可能会将其更改为 whichCorner 类型参数,然后适本地计算 xy 位置。

顺便说一句... drawText 是一个糟糕的变量名——它听起来像一个函数。使用类似 textToDraw 的东西更具可读性。


这是一个修改后的函数,使用了一个atCorner 参数,其中的值为:

        +-----------+ 
        | 0       1 | 
        |           | 
        |           | 
        | 3       2 |
        +-----------+

编辑:使用右对齐段落样式(如 Thilina Chamin Hewagama 所建议)有一些优势。此编辑版本甚至可以处理带有 "\n" 嵌入换行符的文本。

extension UIImage {

    func addText(textToDraw: NSString, atCorner: Int, textColor: UIColor?, textFont: UIFont?) -> UIImage {

        // Setup the font specific variables
        var _textColor: UIColor
        if textColor == nil {
            _textColor = UIColor.white
        } else {
            _textColor = textColor!
        }

        var _textFont: UIFont
        if textFont == nil {
            _textFont = UIFont.systemFont(ofSize: 50)
        } else {
            _textFont = textFont!
        }

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

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

        let titleParagraphStyle = NSMutableParagraphStyle()

        // Setup the font attributes that will be later used to dictate how the text should be drawn
        let textFontAttributes = [
            NSFontAttributeName: _textFont,
            NSForegroundColorAttributeName: _textColor,
            NSParagraphStyleAttributeName: titleParagraphStyle
            ] as [String : Any]

        // get the bounding-box for the string
        var stringSize = textToDraw.size(attributes: textFontAttributes)

        // draw in rect functions like whole numbers
        stringSize.width = ceil(stringSize.width)
        stringSize.height = ceil(stringSize.height)

        var rect = CGRect(origin: CGPoint.zero, size: self.size)

        switch atCorner {

        case 1:
            // top-right
            titleParagraphStyle.alignment = .right

        case 2:
            // bottom-right
            rect.origin.y = self.size.height - stringSize.height
            titleParagraphStyle.alignment = .right

        case 3:
            // bottom-left
            rect.origin.y = self.size.height - stringSize.height

        default:
            // top-left
            // don't need to change anything here
            break

        }

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

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

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

        //Pass the image back up to the caller
        return newImage!
    }

}

关于ios - 在图片右上角绘制文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44306865/

有关ios - 在图片右上角绘制文字的更多相关文章

  1. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. ruby-on-rails - Ruby on Rails - 为文本区域和图片生成列 - 2

    我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  8. ruby - 字符串文字前面的 * 在 ruby​​ 中有什么作用? - 2

    这段代码似乎创建了一个范围从a到z的数组,但我不明白*的作用。有人可以解释一下吗?[*"a".."z"] 最佳答案 它叫做splatoperator.SplattinganLvalueAmaximumofonelvaluemaybesplattedinwhichcaseitisassignedanArrayconsistingoftheremainingrvaluesthatlackcorrespondinglvalues.Iftherightmostlvalueissplattedthenitconsumesallrvaluesw

  9. ruby-on-rails - Rails 3,在RAILS_ROOT上方显示来自本地文件系统的jpg图片 - 2

    我正在尝试找出一种方法来显示来自不在RAILS_ROOT下(在RedHat或Ubuntu环境中)的已安装文件系统的图像。我不想使用符号链接(symboliclink),因为这个应用程序实际上是通过Tomcat部署的,而当我关闭Tomcat时,Tomcat会尝试跟随符号链接(symboliclink)并删除挂载中的所有图像。由于这些文件的数量和大小,将图像放在public/images下也不是一种选择。我查看了send_file,但它只会显示一张图片。我需要在一个格式良好的页面中显示6个请求的图像。由于膨胀,我宁愿不使用Base64编码,但我不知道如何将图像数据与呈现的页面一起传递下去。

  10. 最新版人脸识别小程序 图片识别 生成二维码签到 地图上选点进行位置签到 计算签到距离 课程会议活动打卡日常考勤 上课签到打卡考勤口令签到 - 2

    技术选型1,前端小程序原生MINA框架cssJavaScriptWxml2,管理后台云开发Cms内容管理系统web网页3,数据后台小程序云开发云函数云开发数据库(基于MongoDB)云存储4,人脸识别算法基于百度智能云实现人脸识别一,用户端效果图预览老规矩我们先来看效果图,如果效果图符合你的需求,就继续往下看,如果不符合你的需求,可以跳过。1-1,登录注册页可以看到登录页有注册入口,注册页如下我们的注册,需要管理员审核,审核通过后才可以正常登录使用小程序1-2,个人中心页登录成功以后,我们会进入个人中心页我们在个人中心页可以注册人脸,因为我们做人脸识别签到,需要先注册人脸才可以进行人脸比对,进

随机推荐