Создайте PhotoImage с C ++ Buffer, используя: Python 3.3, Python.Boost и Tkinter

Я использую Tkinter и python.boost на Python 3.3.

Я хочу создать простой графический интерфейс, который показывает изображение в центре. Изображение хранится в классе C ++ с использованием двойных значений. Чтобы показать изображение с помощью tkinter, я должен создать PhotoImage объект.

Я прочитал, что можно создать объект PhotoImage, используя метод Image.fromstring (режим, размер, данные, декодер, параметры). Я думаю: если я создам функцию, которая преобразует мой буфер в std :: string, я смогу создать объект PhotoImage.

Мой класс C ++:

class DoubleImage
{
double* m_dBuffer; // Values from 0 to 1

public:
DoubleImage(const char* fileName, const int width, const int height);

/* Class Functions  */

std::string toString( void ) {
double *pSrc  = m_dBuffer;
int size = getWidth() * getHeight() * getChannels();

char* buffer = new char[size];
char* pbuffer = buffer;

for ( int i = 0; i < size; ++i, ++pSrc, ++pbuffer ) {
*pbuffer = ((char) (*pSrc * 255.0));
}

std::string ret(buffer);

delete[] buffer;

return ret;
}
};

И код поддержки Python:

using namespace boost::python;

BOOST_PYTHON_MODULE(ImageModule)
{

class_<DoubleImage>("DoubleImage", init<const char*, const int, const int>())
.add_property("width", &DoubleImage::getWidth)
.add_property("height", &DoubleImage::getHeight)
.add_property("channels", &DoubleImage::getChannels)
// Some functions ...
.def("toString", &DoubleImage::toString)
;
}

Но когда я запускаю toString в python, он получает эту ошибку:

>>> from ImageModule import *
>>> img = DoubleImage('001.png', 300, 200)
>>> buffer = img.toString()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x86 in position 155: invalid start byte
>>>

У меня два вопроса, во-первых, чего мне не хватает ?? и во-вторых, как только я решил эту ошибку, какие параметры я должен использовать для создания объекта PhotoImage?

2

Решение

Наконец я нашел решение после долгих страданий: P

Сначала функция нанизывать должны быть изменены следующим образом:

std::string DoubleImage::toString( void ) {
ECV_CHECK_ERROR ( m_eType == IT_UKNOWN, "The image is not initialized!" );

double *pSrc  = (double *) m_cvImage.data;
long size = getWidth() * getHeight() * getChannels();

std::string ret(size, ' ');

for ( long i = 0; i < size; ++i, ++pSrc ) {
ret[i] = ((char) (*pSrc * 255.0));
}

return ret;
}

в противном случае результирующий std :: string не будет иметь общую длину (потому что конструктор ищет первый ‘\ 0’). К тому же странная ошибкаUnicodeDecodeError«, только при использовании python 3.3. С помощью python 2.7 проблема решена. Поэтому я рекомендую использовать python 2.7 для обработки изображений.

Затем я установил Модуль PIL (также доступно только на Python 2.7). Затем в python я создаю объект PhotoImage, используя этот код:

>>> from ImageModule import *
>>> from PIL import image
>>> from ImageTk import PhotoImage
>>> img = DoubleImage('001.png', 300, 200)
>>> buffer = img.toString()
>>> img_pil = Image.fromstring('RGB', [300, 200], buffer, 'raw', 'BGR', 300 * 3, 0)
>>> tk_image = PhotoImage(img_pil)

где 300 — изображение с, 200 — высота изображения, RGB — выходной формат, BGR — входной формат (IplImage), а 3 — каналы (3 * 300 шаг изображения). Тогда все работает как шарм 🙂

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]