diff options
Diffstat (limited to 'components/rtgui/common/image_bmp.c')
| -rw-r--r-- | components/rtgui/common/image_bmp.c | 172 |
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 */ |
