Я хотел бы применить один текст сплошной линии к тексту.Это легко получить, используя NSAttributedString
, указав .strokeWidth
.Однако я считаю, что было бы сложно определить, что strokeWidth
должно быть предоставлено UIFont
для визуализации в любой данный pointSize
.Я легко могу сказать, что при размере точки 50 ширина штриха 1 выглядит великолепно.Я интуитивно предположил, что если вы удвоите размер шрифта, вы должны удвоить ширину обводки, таким образом, при масштабировании шрифта обводка будет пропорционально масштабироваться, и в результате толщина обводки будет соответствовать исходному «базовому» размеру шрифта.Однако это не то, что происходит.По мере пропорционального увеличения размера шрифта и ширины обводки ширина обводки становится слишком толстой.
На снимке экрана здесь показана первая строка размера шрифта50 и ширина обводки 1. Следующая строка удваивается, поэтому размер шрифта 100 обводки шириной 2, и это повторяется до последней строки, которая равна 350 против 7.
Я считаю, что это происходит, потому что обводка отображаетсякак внутрь, так и наружу.Его центр находится на краю персонажа, затем он расширяется в обоих направлениях.Вы можете увидеть это, если сравнить эти два изображения, это без примененного обводки.
Так как размер шрифта увеличивается, ширина обводки должнане увеличиваться пропорционально, его нужно увеличивать более медленными темпами, чтобы толщина была одинаковой для всех размеров.Я пытаюсь определить правильный способ вычисления этого значения.
Итак, учитывая базовую конфигурацию, которая выглядит желательной (скажем, размер шрифта 50pt и ширину обводки 1pt) и новый pointSize
(например, 350pt)как правильно рассчитать strokeWidth
?Или, возможно, мне следует использовать другое значение, отличное от pointSize
?
Мой текущий алгоритм, который пропорционально масштабирует его:
let strokeWidth = font.pointSize / 50
(просто решение для x в 1/50 = x/pointSize
)
Вот код, который я использую для рисования этого текста:
let text = "hello"
let imageRect = CGRect(x: 0, y: 0, width: 343 * 3, height: 500 * 3)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let alphaInfo = CGImageAlphaInfo.premultipliedLast.rawValue
let bitmapContext = CGContext(data: nil, width: Int(imageRect.width), height: Int(imageRect.height), bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: alphaInfo)!
bitmapContext.setAlpha(1)
bitmapContext.setTextDrawingMode(CGTextDrawingMode.fill)
//1
bitmapContext.textPosition = CGPoint(x: 40, y: 1080)
let displayLineText1 = CTLineCreateWithAttributedString(NSAttributedString(string: text, attributes: [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 50), .strokeColor: UIColor.red, .strokeWidth: 1]))
CTLineDraw(displayLineText1, bitmapContext)
//2
bitmapContext.textPosition = CGPoint(x: 40, y: 1000)
let displayLineText2 = CTLineCreateWithAttributedString(NSAttributedString(string: text, attributes: [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 100), .strokeColor: UIColor.red, .strokeWidth: 2]))
CTLineDraw(displayLineText2, bitmapContext)
//3
bitmapContext.textPosition = CGPoint(x: 40, y: 875)
let displayLineText3 = CTLineCreateWithAttributedString(NSAttributedString(string: text, attributes: [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 150), .strokeColor: UIColor.red, .strokeWidth: 3]))
CTLineDraw(displayLineText3, bitmapContext)
//4
bitmapContext.textPosition = CGPoint(x: 40, y: 725)
let displayLineText4 = CTLineCreateWithAttributedString(NSAttributedString(string: text, attributes: [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 200), .strokeColor: UIColor.red, .strokeWidth: 4]))
CTLineDraw(displayLineText4, bitmapContext)
//5
bitmapContext.textPosition = CGPoint(x: 40, y: 540)
let displayLineText5 = CTLineCreateWithAttributedString(NSAttributedString(string: text, attributes: [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 250), .strokeColor: UIColor.red, .strokeWidth: 5]))
CTLineDraw(displayLineText5, bitmapContext)
//6
bitmapContext.textPosition = CGPoint(x: 40, y: 310)
let displayLineText6 = CTLineCreateWithAttributedString(NSAttributedString(string: text, attributes: [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 300), .strokeColor: UIColor.red, .strokeWidth: 6]))
CTLineDraw(displayLineText6, bitmapContext)
//7
bitmapContext.textPosition = CGPoint(x: 40, y: 40)
let displayLineText7 = CTLineCreateWithAttributedString(NSAttributedString(string: text, attributes: [.foregroundColor: UIColor.black, .font: UIFont.systemFont(ofSize: 350), .strokeColor: UIColor.red, .strokeWidth: 7]))
CTLineDraw(displayLineText7, bitmapContext)
let textCGImage = bitmapContext.makeImage()!
let textImage = CIImage(cgImage: textCGImage)