图形中的MagickGetImagePixelsMagick很奇怪

时间:2018-11-28 13:17:38

标签: c imagemagick graphicsmagick

我正在尝试使C代码执行简单的调整大小。

这是我使用的代码

#include <stdlib.h>
#include <wand/wand_api.h>

struct ARRAY_BUFFER
{
    void *data;
    unsigned int height;
    unsigned int width;
    int color_type;
    int bit_depth;
};

ExceptionType
check_result(const MagickWand* wand) {
    char *description;
    ExceptionType severity;
    description=MagickGetException(wand, &severity);
    printf("%s %s\n", GetMagickModule(), description);
    if(severity >= 400)
        return 1;
    return 0;
}

int
resize(struct ARRAY_BUFFER* buffer_in,
       struct ARRAY_BUFFER* buffer_out)
{
    MagickWand *wand = NewMagickWand();
    unsigned int status;

    status = MagickSetSize(wand, buffer_in->width, buffer_in->height);
    if(!status) {
        ExceptionType e = check_result(wand);
        if(e >= 400) return 1;
    }

    status = MagickReadImage(wand, "xc:none");
    if(!status) {
        ExceptionType e = check_result(wand);
        if(e >= 400) return 1;
    }

    status = MagickSetImagePixels(wand, 0, 0, buffer_in->width, buffer_in->height, "RGB", CharPixel, buffer_in->data);
    if(!status) {
        ExceptionType e = check_result(wand);
        if(e >= 400) return 1;
    }

    status = MagickResizeImage(wand, buffer_out->width, buffer_out->height, LanczosFilter, 1);
    if(!status) {
        ExceptionType e = check_result(wand);
        if(e >= 400) return 1;
    }
    status = MagickGetImagePixels(wand, 0, 0, buffer_out->width, buffer_out->height, "RGB", CharPixel, buffer_out->data);
    if(!status) {
        ExceptionType e = check_result(wand);
        if(e >= 400) return 1;
    }
    // This line is for deugging
    MagickWriteImage(wand, "test.png");
    return 0;
}

如果我提取输出缓冲区,则图像似乎坏了。图片下方是原始图像和由外部库保存的调整大小后的图像。

原始图像:

The original image

从输出缓冲区生成的图像:

Generated image from output buffer

GM保存的已调整尺寸的图像:

Resized image saved by GM

问题显然是位深度或数据类型问题,但我在Web上找不到有关此问题的任何指南。有我不知道的把戏吗?

(已添加)
这是我的Python代码,可从C缓冲区构建为图像结构

_lib = os.path.join(os.path.dirname(__file__), 'libimage.so')
_lib = ctypes.cdll.LoadLibrary(_lib)
class BYTE_BUFFER(ctypes.Structure):
    _fields_ = [
        ('data', ctypes.c_void_p),
        ('size', ctypes.c_size_t),
    ]
class ARRAY_BUFFER(ctypes.Structure):
    _fields_ = [
        ('data', ctypes.c_void_p),
        ('height', ctypes.c_uint),
        ('width', ctypes.c_uint),
        ('color_type', ctypes.c_int),
        ('bit_depth', ctypes.c_int),
    ]

_lib.resize.argtypes = [
        ctypes.POINTER(ARRAY_BUFFER),
        ctypes.POINTER(ARRAY_BUFFER),
    ]
_lib.resize.restype = ctypes.c_int


def resize(array: np.ndarray, height: int, width: int):
    bit_depth, color_type = _get_array_header(array)
    array_length = height * width * (bit_depth // 8) * 3

    array_buffer = ARRAY_BUFFER(
        array.ctypes.data_as(ctypes.c_void_p),
        array.shape[0],
        array.shape[1],
        __COLOR_TYPE__[color_type],
        bit_depth,
    )
    array_buffer_out = ARRAY_BUFFER(
        ctypes.cast((ctypes.c_uint32 * array_length)(), ctypes.c_void_p),
        height,
        width,
        0,
        0,
    )

    code = _lib.resize(ctypes.byref(array_buffer), ctypes.byref(array_buffer_out))
    if code:
        raise RuntimeError('Resizing failed')

    array_string = (ctypes.c_byte * array_length).from_address(array_buffer.data)
    array = np.frombuffer(array_string, dtype='=u' + str(bit_depth // 8))
    array = np.resize(array, [height, width, 3])
    array = array.squeeze()
    return array

0 个答案:

没有答案
相关问题