mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +08:00
transfer to BMP is ok
This commit is contained in:
parent
4a91d9e7fa
commit
b7964797f1
@ -5,4 +5,6 @@ img.read("test/assets/test.jpg")
|
||||
|
||||
cv.Converter.toRGB565(img)
|
||||
print(str(Utils.b2a_hex(img.data())))
|
||||
cv.Converter.toBMP(img)
|
||||
img.write("test/assets/test.bmp")
|
||||
|
||||
|
@ -22,6 +22,10 @@ class Image(TinyObj):
|
||||
"""Read the image from the specified path, Need implement the `__platform_fopen()`, `__platform_fread()` and `__platform_fclose()`"""
|
||||
...
|
||||
|
||||
def write(self, path: str):
|
||||
"""Write the image to the specified path, Need implement the `__platform_fopen()`, `__platform_fwrite()` and `__platform_fclose()`"""
|
||||
...
|
||||
|
||||
def loadJpeg(self, bytes: any):
|
||||
"""Load the image from bytes"""
|
||||
|
||||
@ -81,3 +85,17 @@ class Converter(TinyObj):
|
||||
@staticmethod
|
||||
def toGray(image: Image):
|
||||
"""Convert the image to Gray"""
|
||||
|
||||
@staticmethod
|
||||
def toBMP(image: Image):
|
||||
"""Convert the image to BMP"""
|
||||
|
||||
@staticmethod
|
||||
def toBGR888(image: Image):
|
||||
"""Convert the image to BGR888"""
|
||||
|
||||
|
||||
class Transformer(TinyObj):
|
||||
@staticmethod
|
||||
def rotateDown(image: Image):
|
||||
"""Rotate the image """
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "PikaCV_Converter.h"
|
||||
#include "PikaCV_Transformer.h"
|
||||
#include "PikaCV_common.h"
|
||||
|
||||
/* Session identifier for input/output functions (name, members and usage are as
|
||||
@ -93,7 +94,7 @@ PIKA_RES Converter_JPEGtoRGB888(PikaObj* image) {
|
||||
return PIKA_RES_ERR_INVALID_PTR;
|
||||
}
|
||||
pika_assert(img->format == PikaCV_ImageFormat_Type_JPEG);
|
||||
uint8_t* data = _Image_getData(image);
|
||||
uint8_t* data = _image_getData(image);
|
||||
if (NULL == data) {
|
||||
__platform_printf("Converter_JPEGtoRGB888: data is NULL\n");
|
||||
return PIKA_RES_ERR_INVALID_PTR;
|
||||
@ -170,7 +171,7 @@ void PikaCV_Converter_toGray(PikaObj* self, PikaObj* image) {
|
||||
|
||||
int size_new = img->height * img->width;
|
||||
Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
|
||||
uint8_t* data = _Image_getData(image);
|
||||
uint8_t* data = _image_getData(image);
|
||||
uint8_t* data_new = arg_getBytes(arg_data_new);
|
||||
if (img->format == PikaCV_ImageFormat_Type_RGB888) {
|
||||
for (int i = 0; i < size_new; i++) {
|
||||
@ -282,3 +283,132 @@ exit:
|
||||
img->size = size_new;
|
||||
arg_deinit(arg_data_new);
|
||||
}
|
||||
|
||||
typedef struct /**** BMP file header structure ****/
|
||||
{
|
||||
unsigned int bfSize; /* Size of file */
|
||||
unsigned short bfReserved1; /* Reserved */
|
||||
unsigned short bfReserved2; /* ... */
|
||||
unsigned int bfOffBits; /* Offset to bitmap data */
|
||||
} BITMAPFILEHEADER;
|
||||
|
||||
typedef struct /**** BMP file info structure ****/
|
||||
{
|
||||
unsigned int biSize; /* Size of info header */
|
||||
int biWidth; /* Width of image */
|
||||
int biHeight; /* Height of image */
|
||||
unsigned short biPlanes; /* Number of color planes */
|
||||
unsigned short biBitCount; /* Number of bits per pixel */
|
||||
unsigned int biCompression; /* Type of compression to use */
|
||||
unsigned int biSizeImage; /* Size of image data */
|
||||
int biXPelsPerMeter; /* X pixels per meter */
|
||||
int biYPelsPerMeter; /* Y pixels per meter */
|
||||
unsigned int biClrUsed; /* Number of colors used */
|
||||
unsigned int biClrImportant; /* Number of important colors */
|
||||
} BITMAPINFOHEADER;
|
||||
|
||||
#define align(value, align) ((((value) + ((align)-1)) / (align)) * (align))
|
||||
|
||||
void PikaCV_Converter_toBMP(PikaObj* self, PikaObj* image) {
|
||||
PikaCV_Image* img = obj_getStruct(image, "image");
|
||||
if (NULL == img) {
|
||||
pika_assert(0);
|
||||
return;
|
||||
}
|
||||
if (img->format == PikaCV_ImageFormat_Type_BMP) {
|
||||
/* do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* convert to BGR */
|
||||
if (img->format != PikaCV_ImageFormat_Type_BGR888) {
|
||||
PikaCV_Converter_toBGR888(self, image);
|
||||
}
|
||||
|
||||
PikaCV_Transformer_rotateDown(self, image);
|
||||
|
||||
BITMAPFILEHEADER bfh;
|
||||
BITMAPINFOHEADER bih;
|
||||
int i = 0, row_align;
|
||||
int width = img->width;
|
||||
int height = img->height;
|
||||
|
||||
// bmp的每行数据的长度要4字节对齐
|
||||
row_align = align(width * 3, 4);
|
||||
|
||||
/* convert to BMP */
|
||||
int size_new = img->height * row_align + 54;
|
||||
Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
|
||||
uint8_t* data = _image_getData(image);
|
||||
uint8_t* data_new = arg_getBytes(arg_data_new);
|
||||
|
||||
unsigned short bfType = 0x4d42; //'BM'
|
||||
bfh.bfReserved1 = 0;
|
||||
bfh.bfReserved2 = 0;
|
||||
bfh.bfSize = 2 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
|
||||
row_align * height;
|
||||
bfh.bfOffBits = 2 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||
|
||||
bih.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bih.biWidth = width;
|
||||
bih.biHeight = height;
|
||||
bih.biPlanes = 1;
|
||||
bih.biBitCount = 24;
|
||||
bih.biCompression = 0;
|
||||
bih.biSizeImage = 0;
|
||||
bih.biXPelsPerMeter = 0;
|
||||
bih.biYPelsPerMeter = 0;
|
||||
bih.biClrUsed = 0;
|
||||
bih.biClrImportant = 0;
|
||||
|
||||
__platform_memset(data_new, 0, size_new);
|
||||
|
||||
__platform_memcpy(data_new, &bfType, sizeof(bfType));
|
||||
__platform_memcpy(data_new + sizeof(bfType), &bfh, sizeof(bfh));
|
||||
__platform_memcpy(data_new + sizeof(bfType) + sizeof(bfh), &bih,
|
||||
sizeof(bih));
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
__platform_memcpy(data_new + sizeof(bfType) + sizeof(bfh) +
|
||||
sizeof(bih) + row_align * i,
|
||||
data + width * 3 * i, width * 3);
|
||||
}
|
||||
|
||||
obj_setBytes(image, "_data", data_new, size_new);
|
||||
img->format = PikaCV_ImageFormat_Type_BMP;
|
||||
img->size = size_new;
|
||||
arg_deinit(arg_data_new);
|
||||
}
|
||||
|
||||
void PikaCV_Converter_toBGR888(PikaObj* self, PikaObj* image) {
|
||||
PikaCV_Image* img = obj_getStruct(image, "image");
|
||||
if (NULL == img) {
|
||||
pika_assert(0);
|
||||
return;
|
||||
}
|
||||
if (img->format == PikaCV_ImageFormat_Type_BGR888) {
|
||||
/* do nothing */
|
||||
return;
|
||||
}
|
||||
/* to RGB888 */
|
||||
if (img->format != PikaCV_ImageFormat_Type_RGB888) {
|
||||
PikaCV_Converter_toRGB888(self, image);
|
||||
}
|
||||
/* to BGR888 */
|
||||
int size_new = img->size;
|
||||
Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
|
||||
uint8_t* data = _image_getData(image);
|
||||
uint8_t* data_new = arg_getBytes(arg_data_new);
|
||||
|
||||
/* RBG888 to BGR888 */
|
||||
for (int i = 0; i < img->size; i += 3) {
|
||||
data_new[i] = data[i + 2];
|
||||
data_new[i + 1] = data[i + 1];
|
||||
data_new[i + 2] = data[i];
|
||||
}
|
||||
|
||||
obj_setBytes(image, "_data", data_new, size_new);
|
||||
img->format = PikaCV_ImageFormat_Type_BGR888;
|
||||
img->size = size_new;
|
||||
arg_deinit(arg_data_new);
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ void PikaCV_Image___init__(PikaObj* self) {
|
||||
.size = 0,
|
||||
};
|
||||
obj_setStruct(self, "image", image);
|
||||
PikaCV_Image_setData(self, NULL, 0);
|
||||
_image_setData(self, NULL, 0);
|
||||
}
|
||||
|
||||
uint8_t* _Image_getData(PikaObj* self) {
|
||||
uint8_t* _image_getData(PikaObj* self) {
|
||||
PikaCV_Image* image = obj_getStruct(self, "image");
|
||||
if (NULL == image) {
|
||||
return NULL;
|
||||
@ -26,7 +26,15 @@ uint8_t* _Image_getData(PikaObj* self) {
|
||||
return obj_getBytes(self, "_data");
|
||||
}
|
||||
|
||||
PIKA_RES PikaCV_Image_setData(PikaObj* self, uint8_t* data, int size) {
|
||||
int _image_getDataSize(PikaObj* self) {
|
||||
PikaCV_Image* image = obj_getStruct(self, "image");
|
||||
if (NULL == image) {
|
||||
return 0;
|
||||
}
|
||||
return obj_getBytesSize(self, "_data");
|
||||
}
|
||||
|
||||
PIKA_RES _image_setData(PikaObj* self, uint8_t* data, int size) {
|
||||
PikaCV_Image* image = obj_getStruct(self, "image");
|
||||
if (NULL == image) {
|
||||
return PIKA_RES_ERR_ARG_NO_FOUND;
|
||||
@ -76,7 +84,7 @@ void PikaCV_Image_loadRGB565(PikaObj* self,
|
||||
image->height = height;
|
||||
image->width = width;
|
||||
image->size = height * width * 2;
|
||||
PikaCV_Image_setData(self, bytes, image->size);
|
||||
_image_setData(self, bytes, image->size);
|
||||
}
|
||||
|
||||
void PikaCV_Image_loadRGB888(PikaObj* self,
|
||||
@ -91,7 +99,7 @@ void PikaCV_Image_loadRGB888(PikaObj* self,
|
||||
image->height = height;
|
||||
image->width = width;
|
||||
image->size = height * width * 3;
|
||||
PikaCV_Image_setData(self, bytes, image->size);
|
||||
_image_setData(self, bytes, image->size);
|
||||
}
|
||||
|
||||
void PikaCV_Image_loadGray(PikaObj* self,
|
||||
@ -106,7 +114,7 @@ void PikaCV_Image_loadGray(PikaObj* self,
|
||||
image->height = height;
|
||||
image->width = width;
|
||||
image->size = height * width;
|
||||
PikaCV_Image_setData(self, bytes, image->size);
|
||||
_image_setData(self, bytes, image->size);
|
||||
}
|
||||
|
||||
void PikaCV_Image_read(PikaObj* self, char* path) {
|
||||
@ -144,7 +152,7 @@ void PikaCV_Image_setPixel(PikaObj* self,
|
||||
if (NULL == image) {
|
||||
return;
|
||||
}
|
||||
uint8_t* data = _Image_getData(self);
|
||||
uint8_t* data = _image_getData(self);
|
||||
if (image->format == PikaCV_ImageFormat_Type_RGB565) {
|
||||
data[(y * image->width + x) * 2 + channel] = value;
|
||||
} else if (image->format == PikaCV_ImageFormat_Type_RGB888) {
|
||||
@ -163,7 +171,7 @@ int PikaCV_Image_getPixel(PikaObj* self, int channel, int x, int y) {
|
||||
if (NULL == image) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t* data = _Image_getData(self);
|
||||
uint8_t* data = _image_getData(self);
|
||||
if (image->format == PikaCV_ImageFormat_Type_RGB565) {
|
||||
return data[(y * image->width + x) * 2 + channel];
|
||||
} else if (image->format == PikaCV_ImageFormat_Type_RGB888) {
|
||||
@ -193,3 +201,22 @@ int PikaCV_Image_width(PikaObj* self) {
|
||||
}
|
||||
return image->width;
|
||||
}
|
||||
|
||||
void PikaCV_Image_write(PikaObj* self, char* path) {
|
||||
uint8_t* data = _image_getData(self);
|
||||
int size = _image_getDataSize(self);
|
||||
if (NULL == data || size <= 0) {
|
||||
obj_setErrorCode(self, PIKA_RES_ERR_OPERATION_FAILED);
|
||||
__platform_printf("PikaCV_Image_write: data is NULL or size is 0\n");
|
||||
return;
|
||||
}
|
||||
FILE* fp = __platform_fopen(path, "wb+");
|
||||
if (NULL == fp) {
|
||||
obj_setErrorCode(self, PIKA_RES_ERR_OPERATION_FAILED);
|
||||
__platform_printf("PikaCV_Image_write: failed to open file: %s\n",
|
||||
path);
|
||||
return;
|
||||
}
|
||||
__platform_fwrite(data, 1, size, fp);
|
||||
__platform_fclose(fp);
|
||||
}
|
||||
|
37
package/PikaCV/PikaCV_Transformer.c
Normal file
37
package/PikaCV/PikaCV_Transformer.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include "PikaCV_Transformer.h"
|
||||
#include "PikaCV_Converter.h"
|
||||
#include "PikaCV_common.h"
|
||||
|
||||
void PikaCV_Transformer_rotateDown(PikaObj* self, PikaObj* image) {
|
||||
PikaCV_Image* img = obj_getStruct(image, "image");
|
||||
if (NULL == img) {
|
||||
pika_assert(0);
|
||||
return;
|
||||
}
|
||||
if (img->format != PikaCV_ImageFormat_Type_BGR888 &&
|
||||
img->format != PikaCV_ImageFormat_Type_RGB888) {
|
||||
obj_setErrorCode(self, PIKA_RES_ERR_OPERATION_FAILED);
|
||||
__platform_printf("unsupported image format\n");
|
||||
return;
|
||||
}
|
||||
int width = img->width;
|
||||
int height = img->height;
|
||||
int size_new = width * height * 3;
|
||||
Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
|
||||
uint8_t* data = _image_getData(image);
|
||||
uint8_t* data_new = arg_getBytes(arg_data_new);
|
||||
int i, j, k;
|
||||
/* rotate */
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
data_new[(height - i - 1) * width * 3 + j * 3 + k] =
|
||||
data[i * width * 3 + j * 3 + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
obj_setBytes(image, "_data", data_new, size_new);
|
||||
img->format = PikaCV_ImageFormat_Type_BGR888;
|
||||
img->size = size_new;
|
||||
arg_deinit(arg_data_new);
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
#include "./3rd-party/tjpgd/src/tjpgd.h"
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
typedef enum PikaCV_ImageFormat_Type {
|
||||
PikaCV_ImageFormat_Type_Unknown = 0,
|
||||
PikaCV_ImageFormat_Type_JPEG,
|
||||
PikaCV_ImageFormat_Type_RGB888,
|
||||
PikaCV_ImageFormat_Type_BGR888,
|
||||
PikaCV_ImageFormat_Type_RGB565,
|
||||
PikaCV_ImageFormat_Type_GRAY,
|
||||
PikaCV_ImageFormat_Type_BMP,
|
||||
} PikaCV_ImageFormat_Type;
|
||||
|
||||
typedef struct PikaCV_Image {
|
||||
@ -15,5 +18,6 @@ typedef struct PikaCV_Image {
|
||||
int size;
|
||||
} PikaCV_Image;
|
||||
|
||||
uint8_t* _Image_getData(PikaObj* self);
|
||||
PIKA_RES PikaCV_Image_setData(PikaObj* self, uint8_t* data, int size);
|
||||
uint8_t* _image_getData(PikaObj* self);
|
||||
PIKA_RES _image_setData(PikaObj* self, uint8_t* data, int size);
|
||||
int _image_getDataSize(PikaObj* self);
|
@ -22,6 +22,10 @@ class Image(TinyObj):
|
||||
"""Read the image from the specified path, Need implement the `__platform_fopen()`, `__platform_fread()` and `__platform_fclose()`"""
|
||||
...
|
||||
|
||||
def write(self, path: str):
|
||||
"""Write the image to the specified path, Need implement the `__platform_fopen()`, `__platform_fwrite()` and `__platform_fclose()`"""
|
||||
...
|
||||
|
||||
def loadJpeg(self, bytes: any):
|
||||
"""Load the image from bytes"""
|
||||
|
||||
@ -81,3 +85,17 @@ class Converter(TinyObj):
|
||||
@staticmethod
|
||||
def toGray(image: Image):
|
||||
"""Convert the image to Gray"""
|
||||
|
||||
@staticmethod
|
||||
def toBMP(image: Image):
|
||||
"""Convert the image to BMP"""
|
||||
|
||||
@staticmethod
|
||||
def toBGR888(image: Image):
|
||||
"""Convert the image to BGR888"""
|
||||
|
||||
|
||||
class Transformer(TinyObj):
|
||||
@staticmethod
|
||||
def rotateDown(image: Image):
|
||||
"""Rotate the image """
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "PikaCV_Converter.h"
|
||||
#include "PikaCV_Transformer.h"
|
||||
#include "PikaCV_common.h"
|
||||
|
||||
/* Session identifier for input/output functions (name, members and usage are as
|
||||
@ -93,7 +94,7 @@ PIKA_RES Converter_JPEGtoRGB888(PikaObj* image) {
|
||||
return PIKA_RES_ERR_INVALID_PTR;
|
||||
}
|
||||
pika_assert(img->format == PikaCV_ImageFormat_Type_JPEG);
|
||||
uint8_t* data = _Image_getData(image);
|
||||
uint8_t* data = _image_getData(image);
|
||||
if (NULL == data) {
|
||||
__platform_printf("Converter_JPEGtoRGB888: data is NULL\n");
|
||||
return PIKA_RES_ERR_INVALID_PTR;
|
||||
@ -170,7 +171,7 @@ void PikaCV_Converter_toGray(PikaObj* self, PikaObj* image) {
|
||||
|
||||
int size_new = img->height * img->width;
|
||||
Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
|
||||
uint8_t* data = _Image_getData(image);
|
||||
uint8_t* data = _image_getData(image);
|
||||
uint8_t* data_new = arg_getBytes(arg_data_new);
|
||||
if (img->format == PikaCV_ImageFormat_Type_RGB888) {
|
||||
for (int i = 0; i < size_new; i++) {
|
||||
@ -282,3 +283,132 @@ exit:
|
||||
img->size = size_new;
|
||||
arg_deinit(arg_data_new);
|
||||
}
|
||||
|
||||
typedef struct /**** BMP file header structure ****/
|
||||
{
|
||||
unsigned int bfSize; /* Size of file */
|
||||
unsigned short bfReserved1; /* Reserved */
|
||||
unsigned short bfReserved2; /* ... */
|
||||
unsigned int bfOffBits; /* Offset to bitmap data */
|
||||
} BITMAPFILEHEADER;
|
||||
|
||||
typedef struct /**** BMP file info structure ****/
|
||||
{
|
||||
unsigned int biSize; /* Size of info header */
|
||||
int biWidth; /* Width of image */
|
||||
int biHeight; /* Height of image */
|
||||
unsigned short biPlanes; /* Number of color planes */
|
||||
unsigned short biBitCount; /* Number of bits per pixel */
|
||||
unsigned int biCompression; /* Type of compression to use */
|
||||
unsigned int biSizeImage; /* Size of image data */
|
||||
int biXPelsPerMeter; /* X pixels per meter */
|
||||
int biYPelsPerMeter; /* Y pixels per meter */
|
||||
unsigned int biClrUsed; /* Number of colors used */
|
||||
unsigned int biClrImportant; /* Number of important colors */
|
||||
} BITMAPINFOHEADER;
|
||||
|
||||
#define align(value, align) ((((value) + ((align)-1)) / (align)) * (align))
|
||||
|
||||
void PikaCV_Converter_toBMP(PikaObj* self, PikaObj* image) {
|
||||
PikaCV_Image* img = obj_getStruct(image, "image");
|
||||
if (NULL == img) {
|
||||
pika_assert(0);
|
||||
return;
|
||||
}
|
||||
if (img->format == PikaCV_ImageFormat_Type_BMP) {
|
||||
/* do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* convert to BGR */
|
||||
if (img->format != PikaCV_ImageFormat_Type_BGR888) {
|
||||
PikaCV_Converter_toBGR888(self, image);
|
||||
}
|
||||
|
||||
PikaCV_Transformer_rotateDown(self, image);
|
||||
|
||||
BITMAPFILEHEADER bfh;
|
||||
BITMAPINFOHEADER bih;
|
||||
int i = 0, row_align;
|
||||
int width = img->width;
|
||||
int height = img->height;
|
||||
|
||||
// bmp的每行数据的长度要4字节对齐
|
||||
row_align = align(width * 3, 4);
|
||||
|
||||
/* convert to BMP */
|
||||
int size_new = img->height * row_align + 54;
|
||||
Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
|
||||
uint8_t* data = _image_getData(image);
|
||||
uint8_t* data_new = arg_getBytes(arg_data_new);
|
||||
|
||||
unsigned short bfType = 0x4d42; //'BM'
|
||||
bfh.bfReserved1 = 0;
|
||||
bfh.bfReserved2 = 0;
|
||||
bfh.bfSize = 2 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
|
||||
row_align * height;
|
||||
bfh.bfOffBits = 2 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||
|
||||
bih.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bih.biWidth = width;
|
||||
bih.biHeight = height;
|
||||
bih.biPlanes = 1;
|
||||
bih.biBitCount = 24;
|
||||
bih.biCompression = 0;
|
||||
bih.biSizeImage = 0;
|
||||
bih.biXPelsPerMeter = 0;
|
||||
bih.biYPelsPerMeter = 0;
|
||||
bih.biClrUsed = 0;
|
||||
bih.biClrImportant = 0;
|
||||
|
||||
__platform_memset(data_new, 0, size_new);
|
||||
|
||||
__platform_memcpy(data_new, &bfType, sizeof(bfType));
|
||||
__platform_memcpy(data_new + sizeof(bfType), &bfh, sizeof(bfh));
|
||||
__platform_memcpy(data_new + sizeof(bfType) + sizeof(bfh), &bih,
|
||||
sizeof(bih));
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
__platform_memcpy(data_new + sizeof(bfType) + sizeof(bfh) +
|
||||
sizeof(bih) + row_align * i,
|
||||
data + width * 3 * i, width * 3);
|
||||
}
|
||||
|
||||
obj_setBytes(image, "_data", data_new, size_new);
|
||||
img->format = PikaCV_ImageFormat_Type_BMP;
|
||||
img->size = size_new;
|
||||
arg_deinit(arg_data_new);
|
||||
}
|
||||
|
||||
void PikaCV_Converter_toBGR888(PikaObj* self, PikaObj* image) {
|
||||
PikaCV_Image* img = obj_getStruct(image, "image");
|
||||
if (NULL == img) {
|
||||
pika_assert(0);
|
||||
return;
|
||||
}
|
||||
if (img->format == PikaCV_ImageFormat_Type_BGR888) {
|
||||
/* do nothing */
|
||||
return;
|
||||
}
|
||||
/* to RGB888 */
|
||||
if (img->format != PikaCV_ImageFormat_Type_RGB888) {
|
||||
PikaCV_Converter_toRGB888(self, image);
|
||||
}
|
||||
/* to BGR888 */
|
||||
int size_new = img->size;
|
||||
Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
|
||||
uint8_t* data = _image_getData(image);
|
||||
uint8_t* data_new = arg_getBytes(arg_data_new);
|
||||
|
||||
/* RBG888 to BGR888 */
|
||||
for (int i = 0; i < img->size; i += 3) {
|
||||
data_new[i] = data[i + 2];
|
||||
data_new[i + 1] = data[i + 1];
|
||||
data_new[i + 2] = data[i];
|
||||
}
|
||||
|
||||
obj_setBytes(image, "_data", data_new, size_new);
|
||||
img->format = PikaCV_ImageFormat_Type_BGR888;
|
||||
img->size = size_new;
|
||||
arg_deinit(arg_data_new);
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ void PikaCV_Image___init__(PikaObj* self) {
|
||||
.size = 0,
|
||||
};
|
||||
obj_setStruct(self, "image", image);
|
||||
PikaCV_Image_setData(self, NULL, 0);
|
||||
_image_setData(self, NULL, 0);
|
||||
}
|
||||
|
||||
uint8_t* _Image_getData(PikaObj* self) {
|
||||
uint8_t* _image_getData(PikaObj* self) {
|
||||
PikaCV_Image* image = obj_getStruct(self, "image");
|
||||
if (NULL == image) {
|
||||
return NULL;
|
||||
@ -26,7 +26,15 @@ uint8_t* _Image_getData(PikaObj* self) {
|
||||
return obj_getBytes(self, "_data");
|
||||
}
|
||||
|
||||
PIKA_RES PikaCV_Image_setData(PikaObj* self, uint8_t* data, int size) {
|
||||
int _image_getDataSize(PikaObj* self) {
|
||||
PikaCV_Image* image = obj_getStruct(self, "image");
|
||||
if (NULL == image) {
|
||||
return 0;
|
||||
}
|
||||
return obj_getBytesSize(self, "_data");
|
||||
}
|
||||
|
||||
PIKA_RES _image_setData(PikaObj* self, uint8_t* data, int size) {
|
||||
PikaCV_Image* image = obj_getStruct(self, "image");
|
||||
if (NULL == image) {
|
||||
return PIKA_RES_ERR_ARG_NO_FOUND;
|
||||
@ -76,7 +84,7 @@ void PikaCV_Image_loadRGB565(PikaObj* self,
|
||||
image->height = height;
|
||||
image->width = width;
|
||||
image->size = height * width * 2;
|
||||
PikaCV_Image_setData(self, bytes, image->size);
|
||||
_image_setData(self, bytes, image->size);
|
||||
}
|
||||
|
||||
void PikaCV_Image_loadRGB888(PikaObj* self,
|
||||
@ -91,7 +99,7 @@ void PikaCV_Image_loadRGB888(PikaObj* self,
|
||||
image->height = height;
|
||||
image->width = width;
|
||||
image->size = height * width * 3;
|
||||
PikaCV_Image_setData(self, bytes, image->size);
|
||||
_image_setData(self, bytes, image->size);
|
||||
}
|
||||
|
||||
void PikaCV_Image_loadGray(PikaObj* self,
|
||||
@ -106,7 +114,7 @@ void PikaCV_Image_loadGray(PikaObj* self,
|
||||
image->height = height;
|
||||
image->width = width;
|
||||
image->size = height * width;
|
||||
PikaCV_Image_setData(self, bytes, image->size);
|
||||
_image_setData(self, bytes, image->size);
|
||||
}
|
||||
|
||||
void PikaCV_Image_read(PikaObj* self, char* path) {
|
||||
@ -144,7 +152,7 @@ void PikaCV_Image_setPixel(PikaObj* self,
|
||||
if (NULL == image) {
|
||||
return;
|
||||
}
|
||||
uint8_t* data = _Image_getData(self);
|
||||
uint8_t* data = _image_getData(self);
|
||||
if (image->format == PikaCV_ImageFormat_Type_RGB565) {
|
||||
data[(y * image->width + x) * 2 + channel] = value;
|
||||
} else if (image->format == PikaCV_ImageFormat_Type_RGB888) {
|
||||
@ -163,7 +171,7 @@ int PikaCV_Image_getPixel(PikaObj* self, int channel, int x, int y) {
|
||||
if (NULL == image) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t* data = _Image_getData(self);
|
||||
uint8_t* data = _image_getData(self);
|
||||
if (image->format == PikaCV_ImageFormat_Type_RGB565) {
|
||||
return data[(y * image->width + x) * 2 + channel];
|
||||
} else if (image->format == PikaCV_ImageFormat_Type_RGB888) {
|
||||
@ -193,3 +201,22 @@ int PikaCV_Image_width(PikaObj* self) {
|
||||
}
|
||||
return image->width;
|
||||
}
|
||||
|
||||
void PikaCV_Image_write(PikaObj* self, char* path) {
|
||||
uint8_t* data = _image_getData(self);
|
||||
int size = _image_getDataSize(self);
|
||||
if (NULL == data || size <= 0) {
|
||||
obj_setErrorCode(self, PIKA_RES_ERR_OPERATION_FAILED);
|
||||
__platform_printf("PikaCV_Image_write: data is NULL or size is 0\n");
|
||||
return;
|
||||
}
|
||||
FILE* fp = __platform_fopen(path, "wb+");
|
||||
if (NULL == fp) {
|
||||
obj_setErrorCode(self, PIKA_RES_ERR_OPERATION_FAILED);
|
||||
__platform_printf("PikaCV_Image_write: failed to open file: %s\n",
|
||||
path);
|
||||
return;
|
||||
}
|
||||
__platform_fwrite(data, 1, size, fp);
|
||||
__platform_fclose(fp);
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
#include "PikaCV_Transformer.h"
|
||||
#include "PikaCV_Converter.h"
|
||||
#include "PikaCV_common.h"
|
||||
|
||||
void PikaCV_Transformer_rotateDown(PikaObj* self, PikaObj* image) {
|
||||
PikaCV_Image* img = obj_getStruct(image, "image");
|
||||
if (NULL == img) {
|
||||
pika_assert(0);
|
||||
return;
|
||||
}
|
||||
if (img->format != PikaCV_ImageFormat_Type_BGR888 &&
|
||||
img->format != PikaCV_ImageFormat_Type_RGB888) {
|
||||
obj_setErrorCode(self, PIKA_RES_ERR_OPERATION_FAILED);
|
||||
__platform_printf("unsupported image format\n");
|
||||
return;
|
||||
}
|
||||
int width = img->width;
|
||||
int height = img->height;
|
||||
int size_new = width * height * 3;
|
||||
Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
|
||||
uint8_t* data = _image_getData(image);
|
||||
uint8_t* data_new = arg_getBytes(arg_data_new);
|
||||
int i, j, k;
|
||||
/* rotate */
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
data_new[(height - i - 1) * width * 3 + j * 3 + k] =
|
||||
data[i * width * 3 + j * 3 + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
obj_setBytes(image, "_data", data_new, size_new);
|
||||
img->format = PikaCV_ImageFormat_Type_BGR888;
|
||||
img->size = size_new;
|
||||
arg_deinit(arg_data_new);
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
#include "./3rd-party/tjpgd/src/tjpgd.h"
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
typedef enum PikaCV_ImageFormat_Type {
|
||||
PikaCV_ImageFormat_Type_Unknown = 0,
|
||||
PikaCV_ImageFormat_Type_JPEG,
|
||||
PikaCV_ImageFormat_Type_RGB888,
|
||||
PikaCV_ImageFormat_Type_BGR888,
|
||||
PikaCV_ImageFormat_Type_RGB565,
|
||||
PikaCV_ImageFormat_Type_GRAY,
|
||||
PikaCV_ImageFormat_Type_BMP,
|
||||
} PikaCV_ImageFormat_Type;
|
||||
|
||||
typedef struct PikaCV_Image {
|
||||
@ -15,5 +18,6 @@ typedef struct PikaCV_Image {
|
||||
int size;
|
||||
} PikaCV_Image;
|
||||
|
||||
uint8_t* _Image_getData(PikaObj* self);
|
||||
PIKA_RES PikaCV_Image_setData(PikaObj* self, uint8_t* data, int size);
|
||||
uint8_t* _image_getData(PikaObj* self);
|
||||
PIKA_RES _image_setData(PikaObj* self, uint8_t* data, int size);
|
||||
int _image_getDataSize(PikaObj* self);
|
@ -2,4 +2,4 @@
|
||||
#define PIKA_VERSION_MINOR 9
|
||||
#define PIKA_VERSION_MICRO 0
|
||||
|
||||
#define PIKA_EDIT_TIME "2022/07/08 18:00:44"
|
||||
#define PIKA_EDIT_TIME "2022/07/11 10:22:03"
|
||||
|
Loading…
x
Reference in New Issue
Block a user