summaryrefslogtreecommitdiff
path: root/components/rtgui/common/image_bmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'components/rtgui/common/image_bmp.c')
-rw-r--r--components/rtgui/common/image_bmp.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/components/rtgui/common/image_bmp.c b/components/rtgui/common/image_bmp.c
index 71f7adbec8..78c60d796b 100644
--- a/components/rtgui/common/image_bmp.c
+++ b/components/rtgui/common/image_bmp.c
@@ -832,6 +832,178 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc,
while (0);
}
+/*
+ * config bitmap header.
+ */
+void rtgui_image_bmp_header_cfg(struct rtgui_image_bmp_header *bhr, rt_int32_t w, rt_int32_t h, rt_uint16_t bits_per_pixel)
+{
+ int image_size = w * h * bits_per_pixel/8;
+ int header_size = sizeof(struct rtgui_image_bmp_header);
+
+ bhr->bfType = 0x4d42; /* BM */
+ bhr->bfSize = header_size + image_size; /* data size */
+ bhr->bfReserved1 = 0;
+ bhr->bfReserved2 = 0;
+ bhr->bfOffBits = header_size;
+
+ bhr->biSize = 40; /* sizeof BITMAPINFOHEADER */
+ bhr->biWidth = w;
+ bhr->biHeight = h;
+ bhr->biPlanes = 1;
+ bhr->biBitCount = bits_per_pixel;
+ bhr->biCompression = BI_BITFIELDS;
+ bhr->biSizeImage = image_size;
+ bhr->biXPelsPerMeter = 0;
+ bhr->biYPelsPerMeter = 0;
+ bhr->biClrUsed = 0;
+ bhr->biClrImportant = 0;
+ if(bhr->biBitCount == 16 && bhr->biCompression == BI_BITFIELDS)
+ {
+ bhr->bfSize += 12;
+ bhr->bfOffBits += 12;
+ }
+}
+
+#define WRITE_CLUSTER_SIZE 2048
+void bmp_align_write(struct rtgui_filerw *file, char *dest, char *src, rt_int32_t len, rt_int32_t *count)
+{
+ rt_int32_t len_bak = len;
+
+ while(len)
+ {
+ if(*count >= WRITE_CLUSTER_SIZE)
+ {
+ rtgui_filerw_write(file, dest, WRITE_CLUSTER_SIZE, 1);
+ *count = 0;
+ }
+ *(dest + *count) = *(src + (len_bak-len));
+ len --;
+ (*count) ++;
+ }
+}
+
+/*
+ * Grab screen and save as a BMP file
+ * MACRO RGB_CONVERT_TO_BGR: If the pixel of colors is BGR mode, defined it.
+ */
+void screenshot(const char *filename)
+{
+ struct rtgui_filerw *file;
+ int w, h, i, pitch;
+ rt_uint16_t *src;
+ rt_uint32_t mask;
+ struct rtgui_image_bmp_header bhr;
+ struct rtgui_graphic_driver *grp = hw_driver;
+#ifdef RGB_CONVERT_TO_BGR
+ int j;
+ rt_uint16_t *line_buf;
+ rt_uint16_t color, tmp;
+#endif
+ char *pixel_buf;
+ rt_int32_t write_count=0;
+
+ file = rtgui_filerw_create_file(filename, "wb");
+ if(file == RT_NULL)
+ {
+ rt_kprintf("create file failed\n");
+ return;
+ }
+
+ w = grp->width;
+ h = grp->height;
+
+ pitch = w * sizeof(rt_uint16_t);
+#ifdef RGB_CONVERT_TO_BGR
+ line_buf = rt_malloc(pitch);
+ if(line_buf == RT_NULL)
+ {
+ rt_kprintf("no memory!\n");
+ return;
+ }
+#endif
+ pixel_buf = rt_malloc(WRITE_CLUSTER_SIZE);
+ if(pixel_buf == RT_NULL)
+ {
+ rt_kprintf("no memory!\n");
+#ifdef RGB_CONVERT_TO_BGR
+ rt_free(line_buf);
+#endif
+ return;
+ }
+
+ rtgui_image_bmp_header_cfg(&bhr, w, h, grp->bits_per_pixel);
+
+ bmp_align_write(file, pixel_buf, (char*)&bhr,
+ sizeof(struct rtgui_image_bmp_header), &write_count);
+
+ if(bhr.biCompression == BI_BITFIELDS)
+ {
+ mask = 0xF800; /* Red Mask */
+ bmp_align_write(file, pixel_buf, (char*)&mask, 4, &write_count);
+ mask = 0x07E0; /* Green Mask */
+ bmp_align_write(file, pixel_buf, (char*)&mask, 4, &write_count);
+ mask = 0x001F; /* Blue Mask */
+ bmp_align_write(file, pixel_buf, (char*)&mask, 4, &write_count);
+ }
+ rtgui_screen_lock(RT_WAITING_FOREVER);
+ if(grp->framebuffer != RT_NULL)
+ {
+ src = (rt_uint16_t*)grp->framebuffer;
+ src += w * h;
+ for(i=0; i<h; i++)
+ {
+ src -= w;
+#ifdef RGB_CONVERT_TO_BGR
+ for(j=0; j<w; j++)
+ {
+ tmp = *(src + j);
+ color = (tmp & 0x001F)<<11;
+ color += (tmp & 0x07E0);
+ color += (tmp & 0xF800)>>11;
+
+ *(line_buf + i) = color;
+ }
+ bmp_align_write(file, pixel_buf, (char*)line_buf, pitch, &write_count);
+#else
+ bmp_align_write(file, pixel_buf, (char*)src, pitch, &write_count);
+#endif
+ }
+ }
+ else
+ {
+ rtgui_color_t pixel_color;
+ rt_uint16_t write_color;
+ int x;
+ for(i=h-1; i>=0; i--)
+ {
+ x = 0;
+ if(i%10==0)rt_kprintf(">",i);
+ while(x < w)
+ {
+ grp->ops->get_pixel(&pixel_color, x, i);
+ write_color = rtgui_color_to_565p(pixel_color);
+ bmp_align_write(file, pixel_buf, (char*)&write_color,
+ sizeof(rt_uint16_t), &write_count);
+ x++;
+ }
+ }
+ }
+ /* write The tail of the last */
+ if(write_count < WRITE_CLUSTER_SIZE)
+ rtgui_filerw_write(file, pixel_buf, write_count, 1);
+ rtgui_screen_unlock();
+#ifdef RGB_CONVERT_TO_BGR
+ rt_free(line_buf);
+#endif
+ rt_free(pixel_buf);
+ rt_kprintf("bmp create succeed.\n");
+ rtgui_filerw_close(file);
+}
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(screenshot, usage: screenshot(filename));
+#endif
+
void rtgui_image_bmp_init()
{
/* register bmp on image system */