добавить C / C ++ код встраивания Python. вся проблема в коде c, я не знаю, как получить значение пикселя.
код Python:
import Image
format = ""mode = ""size = ""data = list()
def getImage(file):
im = Image.open(file)
global format
global mode
global size
global data
format = im.format
mode = im.mode
size = im.size
width, height = im.size
for x in range(0, height):
for y in range(0, width):
data.append(im.getpixel((x,y)))
return None
в коде C / C ++
Я получаю длину данных равна 0. Есть ли проблемы из двух для цикла?
void loadImage(char *file) {
Image* img = NULL;
Py_Initialize();
if ( !Py_IsInitialized() ) {
std::cerr<<"Python initalize failed.\n";
return NULL;
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *pName, *pModule, *pFunc, *pArgs;
pName = PyString_FromString("loadImage");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if ( !pModule ) {
PyErr_Print();
std::cerr<<"import loadImage module faild, please confirm where the file 'loadImage.py' is.\n";
return NULL;
}
pFunc = PyObject_GetAttrString(pModule, "getImage");
if ( !pFunc ) {
PyErr_Print();
std::cerr<<"Can't find method getImage in loadImage module.\n";
return NULL;
}
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", file));
PyObject_CallObject(pFunc, pArgs);
PyObject *pFormat, *pMode, *pSize, *pData, *pSeq, *pPixel;
pFormat = PyObject_GetAttrString(pModule, "format");
pMode = PyObject_GetAttrString(pModule, "mode");
pSize = PyObject_GetAttrString(pModule, "size");
if ( !PyTuple_Check(pSize) ) {
std::cerr<<"pSize is not tupple object.\n";
return NULL;
}
pData = PyObject_GetAttrString(pModule, "data");
if ( !pData ) {
std::cerr<<"pData is null.\n";
return NULL;
}
if ( !PyList_Check(pData) ) {
std::cerr<<"pData is not list object.\n";
return NULL;
}
int n = PyList_GET_SIZE(pData);
std::cerr<<n<<"\n";
Py_DECREF(pData);
Py_DECREF(pFunc);
Py_DECREF(pModule);
Py_DECREF(pArgs);
std::cerr<<"Py_DECREF over.\n";
}
Я получаю, что длина pData (это n) равна 0.
Ну, ваш код может быть буквально заменен одной строкой:
data = list(Image.open(file).getdata())
getdata
Метод объектов Image возвращает пиксели, упакованные в список, построчно. Если они нужны вам в порядке колонки (как вы делаете), примените .transpose
сначала с соответствующими аргументами. Результат все равно будет значительно быстрее и проще, чем итерации по всем пикселям.
Вы не проверяете возвращаемое значение из PyObject_CallObject
, Это могло бы вернуться NULL
(Исключение Python), и, следовательно, не удалось изменить data
список.
Вы должны проверить каждый Вы вызываете API-интерфейс Python, поскольку обработка исключений очень важна для правильной работы интерпретатора.
Если вы получите NULL
, ты можешь позвонить PyErr_Print()
чтобы распечатать трассировку stderr
(cerr
).
Код Python, который вы запускаете, вызывая PyObject_CallObject
вероятно выбрасывает исключение.
NULL означает исключение. Вы можете использовать различные функции API Python, чтобы получить в
фактическая ошибка: http://docs.python.org/c-api/exceptions.html. Это, наверное, самое простое.
if( PyObject_CallObject(pFunc, pArgs ) == NULL )
{
// Print the exception (a traceback may or may not be available)
PyErr_Print();
// Do any cleanup...
// Always return NULL after a python api function returns NULL.
return NULL;
}
Проблема может быть вызвана Python версии 2.7 на моем компьютере. Я перешел на python 3.2, весь код может получить идеальный возврат.