简体   繁体   中英

MagickCommandGenesis always returns MagickFalse

There is really not much relevant info, and official manual makes me cry. I'm trying to run custom scripts via MagickCommandGenesis because I gave up in attempt to convert some scripts into clean c code with API usage. However, this piece of code:

    //char* cmdargs[] = { "convert", "-rotate", "-90" };
    char* cmdargs[] = { "-rotate", "-90" };
    int argcount = 2;

    ExceptionInfo* e = AcquireExceptionInfo();
    GetExceptionInfo(e);
    MagickBooleanType cmdres = MagickCommandGenesis(wand->image_info, ConvertImageCommand, argcount, cmdargs, NULL, e);

    if (e->severity != UndefinedException || cmdres == MagickFalse) {
        syslog(LOG_NOTICE, "mwb::error:%s", e->severity != UndefinedException ? "derp" : "undefined");
    }

always writes "undefined", ie MagickCommandGenesis returned false, but not throwed exception.

I can't use temporary files to read or write from, I want to do all operations in memory, therefore wand is read via MagickReadImageBlob. Blob is absolutely valid, I can do any API operations and finally draw image on screen, the only thing that not works is command run.

The only one relevant question I found is here but it not so useful. Even more, OP used read and write in files and still got the error. There is answer marked as accepted, but it suggest to use MagickCommandGenesis , what I do already.

Upd:

I figured out that image_info member of MagickWand actually has nothing (probably it just initialized with defaults and not used by MagickWand at all). So now I looking for proper way to instantiate ImageInfo structure from memory blob. That's what I tried:

    char* cmdargs[] = { "-rotate", "-90" };
    int argcount = 2;

    ExceptionInfo* e = AcquireExceptionInfo();
    GetExceptionInfo(e);

    size_t len;
    u_char* blob = MagickGetImageBlob(wand, &len);
    ImageInfo* info = CloneImageInfo(NULL);
    SetImageInfoBlob(info, blob, len);

    MagickBooleanType cmdres = MagickCommandGenesis(info, ConvertImageCommand, argcount, cmdargs, NULL, e);

    MagickWand* target = NewMagickWand();
    MagickReadImageBlob(target, info->blob, info->length);
    // DestroyMagickWand(wand);
    wand = target;

    syslog(LOG_NOTICE, "mwb::blob is %zu", MagickGetImageWidth(target));

    if (e->severity != UndefinedException || cmdres == MagickFalse) {
        syslog(LOG_NOTICE, "mwb::error:%s", e->severity != UndefinedException ? "derp" : "undefined");
    }

Unfortunately, I still get "undefined" error, so MagickCommandGenesis still returns false, but don't throws exception.

Two items to consider.

First: MagickCommandGenesis is expecting a full, not partial, command. Example

 convert source.png -rotate -90 out.png

Second: ImageInfo pointer should be newly allocate memory for the command process to act against. Use AcquireImageInfo() , as giving wand->image_info will result in undefined behavior.

Ideally you should just use C-API methods exclusively, but you can mix existing MagickWand instances with MagickCommand by leveraging the memory program register protocol mpr: .

MagickWand *wand = NewMagickWand();
MagickReadImage(wand, "rose:");
MagickNegateImage(wand, 1); // For example, negate image
// Hand-off image to memory program register
MagickWriteImage(wand, "mpr:my_label");
// Build full command
char* cmdargs[] = {"convert",
                   "mpr:my_label",
                   "-rotate",
                   "-90",
                   "output.png", // Or to another mpr:
                   NULL};
 int argcount = 5;
 // Allocate memory for MagickCommand
 ImageInfo * info = AcquireImageInfo();
 ExceptionInfo* e = AcquireExceptionInfo();
 // Execute command
 MagickCommandGenesis(info, ConvertImageCommand, argcount, cmdargs, NULL, e);
 wand = DestroyMagickWand(wand);
 /* Error handling omitted */

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM