Оказалось что с PIL есть проблемы с 16-бит одноцветными изображениями. Причём серьёзные.
http://stackoverflow.com/questions/7363 ... 16-bit-pgm
Возможно будет иметь смысл сделать прямое чтение .pgm (формат когда human-readable байты написаны циферками подряд) в Numpy (просто заполнить строчку байтами или дву-байтами), а всё остальное (jpg, png, bmp) прогонять предварительно через PIL.
Операцию поворота из матрицы inkscape накладывать в numpy.
Тестовый png:
http://kalyaev.com/2012/20120129/png-0-14.png
Объяснение что получается:

- inkscape_image.png (7.23 КБ) 3566 просмотров
Через pix = im.load() аналогичные значения.
Похоже, вначале надо прогонять через палитру, иначе что-то странное с цветами в PIL.
Попытка вывести вручную палитру подтверждает мысль:
Код: Выделить всё
('RGB;L', '
\x00\x00\x00 \x01\x01\x01 \x02\x02\x02 \x05\x05\x05 \x06\x06\x06
\x07\x07\x07 \x08\x08\x08 \t\t\t \n\n\n \x0b\x0b\x0b
\x0c\x0c\x0c \x0e\x0e\x0e \x0f\x0f\x0f \x80\x80\x80 \xff\xff\xff....)
\t = \x09, \n=\x10
Как пользоваться: ищем на картинке правый верхний квадратик (серый RGB=128,128,128). У него индекс 3 или (3,0) в зависимости от метода. Цвет должен был быть 128, но im.getdata()[3] даёт значение "13" (смотрим в нижнюю табличку номеров цветов на картинке, правое верхнее значение). Далее смотрим в приведённый выше массив троек (RGB) палитры текущего изображения, ищем 13-ую тройку, находим "\x80\x80\x80". Т.к. у нас серое изображение, то берём любую компоненту и переводим её в десятиричную систему. 0x80=8*16+0=128, что как раз соответствует правому верхнему значению на исходной PNG-картинке....
Иными словами, вначале надо провести сопоставление байт через таблицу палитры, либо сконвертировать в "линейную" палитру со значениями 0..255. Так же всё очевиднее становится отсутствие 16-битных изображений в PIL
В итоге заработало так:
Код: Выделить всё
import Image, ImagePalette, numpy
file="png-0-14.png"
im = Image.open(file)
im_format,im_palette=im.palette.getdata()
out=""
for color in im.getdata():
out=out+im_palette[color*3]
# gcodetools.error(("getdata[",color,"]=",im_palette[color*3]),"warning")
gcodetools.error(("out:",out),"warning")
imgBeforeTransform = numpy.fromstring(out,numpy.uint8)
imgBeforeTransform = numpy.reshape(imgBeforeTransform,(4,4))
gcodetools.error((imgBeforeTransform),"error")
Распечатает:
Код: Выделить всё
('out:', '\x00\x01\x02\x80\x05\x06\x07\x08\t\n\x0b\x0c\xff\x0e\x0f\xff'), т.е. искомую строку из исходного PNG.
[[ 0 1 2 128]
[ 5 6 7 8]
[ 9 10 11 12]
[255 14 15 255]]
Так что можно передавать в numpy и настанет счастье....