LINUX.ORG.RU

Как рисовать текст на картинке (не через PIL)

 , , ,


0

3

Нужна простая в-одном-файле графическая библиотека:

1) использующая только struct или другие базовые модули
2) работающая и в Linux, и в Windows
3) позволяющая выводить текст безо всяких шрифтов (т.е. либо встроенные матрицы букв, либо прилагающийся битмап с буквами).

Работать она должна примерно так:

import coolbitmap

img = CoolBitmap(400, 250, 'white')
img.draw_text(10, 10, 'C', 'black')
img.draw_text(20, 10, 'ool', 'blue')
img.draw_pixel(25, 15, 'red')
img.save_to('cool.bmp')
img.close()

Сраный говно-комбайн PIL, не удовлетворяющий ни одному из перечисленных пунктов, не предлагать.

★★★★

Ответ на: комментарий от lovesan

Вот пример, который рисует смайл:

#!/usr/bin/env python2

import math, struct

mult4 = lambda n: int(math.ceil(n/4))*4
mult8 = lambda n: int(math.ceil(n/8))*8
lh = lambda n: struct.pack("<h", n)
li = lambda n: struct.pack("<i", n)

def bmp(rows, w):
    h, wB = len(rows), int(mult8(w)/8)
    s, pad = li(mult4(wB)*h+0x20), [0]*(mult4(wB)-wB)
    s = li(mult4(w)*h+0x20)
    return (b"BM" + s + b"\x00\x00\x00\x00\x20\x00\x00\x00\x0C\x00\x00\x00" +
            lh(w) + lh(h) + b"\x01\x00\x01\x00\xff\xff\xff\x00\x00\x00" +
            b"".join([bytes(row+pad) for row in reversed(rows)]))

smile = [[0xFF], [0x81], [0xA5], [0x81], [0xA5], [0xBD], [0x81], [0xFF]]
buf = bmp(smile, 8)
f = open('image.bmp', 'wb')
f.write(buf)
fh.close()

Его нужно доработать так, чтобы он рисовал 26 букв латинского алфавита.

Novator ★★★★ ()
Ответ на: комментарий от lovesan

Второй пример, который рисует точки:

#!/usr/bin/env python2

from struct import pack

class Bitmap():
  def __init__(s, width, height):
    s._bfType = 19778 # Bitmap signature
    s._bfReserved1 = 0
    s._bfReserved2 = 0
    s._bcPlanes = 1
    s._bcSize = 12
    s._bcBitCount = 24
    s._bfOffBits = 26
    s._bcWidth = width
    s._bcHeight = height
    s._bfSize = 26+s._bcWidth*3*s._bcHeight
    s.clear()

  def clear(s):
    s._graphics = [(0,0,0)]*s._bcWidth*s._bcHeight

  def setPixel(s, x, y, color):
    if isinstance(color, tuple):
      if x<0 or y<0 or x>s._bcWidth-1 or y>s._bcHeight-1:
        raise ValueError('Coords out of range')
      if len(color) != 3:
        raise ValueError('Color must be a tuple of 3 elems')
      s._graphics[y*s._bcWidth+x] = (color[2], color[1], color[0])
    else:
      raise ValueError('Color must be a tuple of 3 elems')

  def write(s, file):
    with open(file, 'wb') as f:
      f.write(pack('<HLHHL', 
                   s._bfType, 
                   s._bfSize, 
                   s._bfReserved1, 
                   s._bfReserved2, 
                   s._bfOffBits)) # Writing BITMAPFILEHEADER
      f.write(pack('<LHHHH', 
                   s._bcSize, 
                   s._bcWidth, 
                   s._bcHeight, 
                   s._bcPlanes, 
                   s._bcBitCount)) # Writing BITMAPINFO
      for px in s._graphics:
        f.write(pack('<BBB', *px))
      for i in range (0, (s._bcWidth*3) % 4):
        f.write(pack('B', 0))

side = 520
b = Bitmap(side, side)
for j in range(0, side):
    b.setPixel(j, j, (255, 0, 0))
    b.setPixel(j, side-j-1, (255, 0, 0))
    b.setPixel(j, 0, (255, 0, 0))
    b.setPixel(j, side-1, (255, 0, 0))
    b.setPixel(0, j, (255, 0, 0))
    b.setPixel(side-1, j, (255, 0, 0))
b.write('image2.bmp')

Задача та же самая.

Novator ★★★★ ()
Последнее исправление: Novator (всего исправлений: 2)
Ответ на: комментарий от Novator

Его нужно доработать так, чтобы он рисовал 26 букв латинского алфавита.

Похоже, его реально быстрее доработать, чем найти готовое. В питоне обычно используют сишные библиотеки, если таковые есть. А по этой задаче они есть.

monk ★★★★★ ()
Ответ на: комментарий от monk

В питоне обычно используют сишные библиотеки, если таковые есть. А по этой задаче они есть.

Если есть такие базовые библиотеки - назови их.

Novator ★★★★ ()
Последнее исправление: Novator (всего исправлений: 1)
Ответ на: комментарий от Novator

Если есть такие базовые библиотеки - назови их.

Так написали же: opencv, SDL, ...

Ещё есть: https://github.com/swistakm/pyimgui (всё как хочешь, и шрифт битмапом и ниакаких зависимостей кроме переносимой C++ библиотеки)

monk ★★★★★ ()