0

add c/c++ code embedding python. all problem is in c code, I don't known how to get the pixel value.

python code:

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

in C/C++ code My get the data length is 0. Any problems of the two for loop?

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";
}

I get the lenght of pData(is n) is 0.

SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
Yuansheng liu
  • 165
  • 1
  • 2
  • 10
  • You're not calling your function, so `data` is never populated? Also, why in the world would you use a global variable for that? – kindall Sep 08 '12 at 01:10
  • oh... I know, this code is moddify many times, the last version is that, but i promise it isn't like that at the original version. – Yuansheng liu Sep 08 '12 at 05:20

4 Answers4

1

Well, your code can literally be replaced with a single line:

data = list(Image.open(file).getdata())

The getdata method of Image objects returns the pixels packed into a list, line-by-line. If you need them in column-major order (as you are doing), apply .transpose with the appropriate arguments first. The result will still be substantially faster and simpler than iterating over all the pixels.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
0

You aren't checking the return value from PyObject_CallObject. It might have returned NULL (Python exception), and consequently failed to modify the data list.

You should check every Python API call you make, since exception handling is critically important to making the interpreter work correctly.

If you do get a NULL, you can call PyErr_Print() to get the traceback printed out to stderr (cerr).

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • I had output the values of format, mode, size, work well, i got their correct value. Only data is error, get the lenght of data is 0. When I set the init value of data = [1, 3, 5, ] in python code, then i can get length of data is 3. I don't know why the pixel value hav't append to data list. – Yuansheng liu Sep 08 '12 at 04:06
  • Well, the function might have thrown an exception *in the loop*...you still need to check its return value! Maybe you should throw some print statements in there to check whether the loop is even being executed at all. – nneonneo Sep 08 '12 at 04:15
  • Your are right. I should check the return value, PyObject_CallObject return me a NULL, so terrible. I also code like this "data = list(im.getdata())". But PyObject_CallObject always return NULL for me. – Yuansheng liu Sep 08 '12 at 04:31
  • oh...no... this function return None is correct. I code return None in python code. – Yuansheng liu Sep 08 '12 at 04:36
  • `NULL` is not the same as `None` in the Python C API. None has a particular non-NULL value since it's a Python object: `Py_None`. If a `PyObject *` function returns `NULL`, it surely encountered an exception: this is the rule of the C API. – nneonneo Sep 08 '12 at 04:37
  • Try using `PyErr_Print` after the function returns NULL to get some information on the exception. – nneonneo Sep 08 '12 at 04:38
  • shit... got this error: ImportError: The _imaging C module is not installed – Yuansheng liu Sep 08 '12 at 04:47
0

The Python code you run by calling PyObject_CallObject is probably throwing an exception.

NULL means an exception was thrown. You can use various python api functions to get at the actual error: http://docs.python.org/c-api/exceptions.html. This is probably the simplest.

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;
}
jjm
  • 6,028
  • 2
  • 24
  • 27
  • many tks, print this error: ImportError: The _imaging C module is not installed. – Yuansheng liu Sep 08 '12 at 04:48
  • I can't found how to solve this problem. I asked the another question.http://stackoverflow.com/questions/12328895/c-c-embedding-python-error-importerror-the-imaging-c-module-is-not-installe – Yuansheng liu Sep 08 '12 at 08:41
0

The problem may caused by the python version 2.7 in my computer. I changed to python 3.2, all code can got ideal return.

Yuansheng liu
  • 165
  • 1
  • 2
  • 10