Я пытаюсь создать код 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](https://i.stack.imgur.com/1rZP1.png)
Сгенерированное изображение из выходного буфера:
![Generated image from output buffer](https://i.stack.imgur.com/SuvzX.png)
Изображение с измененным размером, сохраненное GM:
![Resized image saved by GM](https://i.stack.imgur.com/2t3zd.png)
Проблема, очевидно, связана с проблемой битовой глубины или типа данных, но я не смог найтилюбое руководство по этой проблеме в Интернете.Есть какой-то трюк, который я не знал?
(добавлено)
Это мой код 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