1
0

demo_view_bmp.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * 程序清单:bmp_zoom演示
  3. */
  4. #include "demo_view.h"
  5. #include <rtgui/dc.h>
  6. #include <rtgui/image.h>
  7. #include <rtgui/image_bmp.h>
  8. #include <rtgui/widgets/label.h>
  9. #include <rtgui/widgets/button.h>
  10. #include <rtgui/widgets/textbox.h>
  11. #include <rtgui/widgets/container.h>
  12. #if defined(RTGUI_USING_DFS_FILERW)
  13. struct demo_bmp_dt
  14. {
  15. float scale, angle;
  16. char *filename;
  17. struct rtgui_image *image;
  18. struct rtgui_image *showimg;
  19. rtgui_container_t *showbox;
  20. rtgui_textbox_t *box;
  21. rtgui_rect_t lastrect;
  22. }bmpdt;
  23. rt_bool_t demo_bitmap_showbox(struct rtgui_object* object, struct rtgui_event* event)
  24. {
  25. rtgui_container_t *container;
  26. rtgui_widget_t *widget;
  27. RT_ASSERT(object != RT_NULL);
  28. container = RTGUI_CONTAINER(object);
  29. widget = RTGUI_WIDGET(object);
  30. if(event->type == RTGUI_EVENT_PAINT)
  31. {
  32. int w, h;
  33. rtgui_rect_t rect;
  34. struct rtgui_dc *dc;
  35. struct rtgui_image *image = bmpdt.showimg;
  36. /* 如果从其他标签切换到当前标签, image应该是RT_NULL, 重置它 */
  37. if(image == RT_NULL && bmpdt.image != RT_NULL)
  38. {
  39. image = bmpdt.image;
  40. bmpdt.scale = 1.0f;
  41. bmpdt.angle = 0.0f;
  42. rtgui_widget_get_rect(RTGUI_WIDGET(bmpdt.showbox), &bmpdt.lastrect);
  43. rtgui_rect_inflate(&bmpdt.lastrect, -RTGUI_WIDGET_BORDER(bmpdt.showbox));
  44. }
  45. dc = rtgui_dc_begin_drawing(widget);
  46. if (dc == RT_NULL)
  47. return RT_FALSE;
  48. rtgui_widget_get_rect(widget, &rect);
  49. /* 在绘制边框后, 再将rect缩小填充背景, 可以降低闪烁现象 */
  50. rtgui_dc_draw_border(dc, &rect, RTGUI_WIDGET_BORDER_STYLE(widget));
  51. rtgui_rect_inflate(&rect, -RTGUI_WIDGET_BORDER(widget));
  52. w = rtgui_rect_width(bmpdt.lastrect);
  53. h = rtgui_rect_height(bmpdt.lastrect);
  54. if(w > rtgui_rect_width(rect)) w = rtgui_rect_width(rect);
  55. if(h > rtgui_rect_height(rect)) h = rtgui_rect_height(rect);
  56. /* fill container with background */
  57. /*
  58. * 参数lastrect会记录上一次绘图所用区域
  59. * 每次重绘时,只需与lastrect比较,即可得知那些背景区域需要刷新
  60. * 例如当放大图片时,lastrect比当前绘图区小,所有无需更新背景区,
  61. * 当缩小图片时, 也仅需要更新绘图区比lastrect大的区域.
  62. */
  63. if(image != RT_NULL)
  64. { /* 减少不必要的绘图 */
  65. rtgui_rect_t rc;
  66. if(w > image->w)
  67. {
  68. rc.x1 = image->w;
  69. rc.y1 = bmpdt.lastrect.y1;
  70. rc.x2 = bmpdt.lastrect.x2;
  71. rc.y2 = (h > image->h) ? image->h : bmpdt.lastrect.y2;
  72. rtgui_dc_fill_rect(dc, &rc);
  73. }
  74. if(h > image->h)
  75. {
  76. rc.x1 = bmpdt.lastrect.x1;
  77. rc.y1 = image->h;
  78. rc.x2 = bmpdt.lastrect.x2;
  79. rc.y2 = bmpdt.lastrect.y2;
  80. rtgui_dc_fill_rect(dc, &rc);
  81. }
  82. }
  83. else
  84. rtgui_dc_fill_rect(dc, &bmpdt.lastrect);
  85. /* 将图像数据blit到画布上 */
  86. if (image != RT_NULL)
  87. {
  88. int value;
  89. rtgui_image_blit(image, dc, &rect);
  90. bmpdt.lastrect.x1 = bmpdt.lastrect.y1 = RTGUI_WIDGET_BORDER(bmpdt.showbox);
  91. if(image->w > rtgui_rect_width(rect))
  92. value = rtgui_rect_width(rect);
  93. else
  94. value = image->w;
  95. bmpdt.lastrect.x2 = bmpdt.lastrect.x1 + value;
  96. if(image->h > rtgui_rect_height(rect))
  97. value = rtgui_rect_height(rect);
  98. else
  99. value = image->h;
  100. bmpdt.lastrect.y2 = bmpdt.lastrect.y1 + value;
  101. }
  102. rtgui_dc_end_drawing(dc);
  103. return RT_FALSE;
  104. }
  105. return rtgui_container_event_handler(object, event);
  106. }
  107. void demo_bitmap_open(struct rtgui_object* object, struct rtgui_event* event)
  108. {
  109. char *str;
  110. rtgui_button_t *button = RTGUI_BUTTON(object);
  111. /* 从textbox控件中取得文件名 */
  112. str = (char*)rtgui_textbox_get_value(bmpdt.box);
  113. if(str == RT_NULL) return;
  114. if(*str == '/' && (rt_strstr(str, ".bmp")!=RT_NULL || rt_strstr(str, ".BMP")!=RT_NULL))
  115. { /* 如果是bmp文件, 且文件名有效, 则读入图像数据 */
  116. if(bmpdt.filename != RT_NULL)
  117. rt_free(bmpdt.filename);
  118. bmpdt.filename = rt_strdup(str);
  119. if(bmpdt.image != RT_NULL)
  120. rtgui_image_destroy(bmpdt.image);
  121. bmpdt.image = rtgui_image_create_from_file("bmp", bmpdt.filename, RT_TRUE);
  122. if(bmpdt.image != RT_NULL)
  123. {
  124. bmpdt.showimg = bmpdt.image;
  125. bmpdt.scale = 1.0;
  126. bmpdt.angle = 0.0;
  127. rtgui_widget_update(RTGUI_WIDGET(bmpdt.showbox));
  128. }
  129. }
  130. else
  131. rt_kprintf("Bad filename!");
  132. }
  133. void demo_image_zoom_in(struct rtgui_object* object, struct rtgui_event* event)
  134. {
  135. rtgui_button_t *button = RTGUI_BUTTON(object);
  136. if (bmpdt.image == RT_NULL) return;
  137. if (bmpdt.scale > 0.45)
  138. { /* 更新缩放倍率 */
  139. if (bmpdt.scale > 1.0) bmpdt.scale -= (float)0.5;
  140. else bmpdt.scale -= (float)0.1;
  141. }
  142. /* 根据缩放倍率, 缩放原始图形, 并得到新图形的指针 */
  143. bmpdt.showimg = rtgui_image_zoom(bmpdt.image, bmpdt.scale, bmpdt.scale, RTGUI_IMG_ZOOM_BILINEAR);
  144. if (bmpdt.showimg != RT_NULL)
  145. rtgui_widget_update(RTGUI_WIDGET(bmpdt.showbox));
  146. else
  147. return;
  148. if(bmpdt.showimg != bmpdt.image)
  149. { /* 释放掉新图形所用的资源 */
  150. rtgui_image_destroy(bmpdt.showimg);
  151. bmpdt.showimg = RT_NULL;
  152. }
  153. }
  154. void demo_image_zoom_out(struct rtgui_object* object, struct rtgui_event* event)
  155. {
  156. rtgui_button_t *button = RTGUI_BUTTON(object);
  157. if (bmpdt.image == RT_NULL) return;
  158. if (bmpdt.scale < 4.95)
  159. { /* 更新缩放倍率 */
  160. if (bmpdt.scale > 0.95) bmpdt.scale += (float)0.5;
  161. else bmpdt.scale += (float)0.1;
  162. }
  163. bmpdt.showimg = rtgui_image_zoom(bmpdt.image, bmpdt.scale, bmpdt.scale, RTGUI_IMG_ZOOM_BILINEAR);
  164. if (bmpdt.showimg != RT_NULL)
  165. rtgui_widget_update(RTGUI_WIDGET(bmpdt.showbox));
  166. else
  167. return;
  168. if(bmpdt.showimg != bmpdt.image)
  169. {
  170. rtgui_image_destroy(bmpdt.showimg);
  171. bmpdt.showimg = RT_NULL;
  172. }
  173. }
  174. void demo_image_rotate(struct rtgui_object* object, struct rtgui_event* event)
  175. {
  176. rtgui_button_t *button = RTGUI_BUTTON(object);
  177. if (bmpdt.image == RT_NULL) return;
  178. /* 更新图像旋转角度 */
  179. if (bmpdt.angle < 360.0)
  180. bmpdt.angle += (float)1.0;
  181. else
  182. bmpdt.angle = 0.0;
  183. /* 调用旋转函数执行旋转, 并取得一个新的图像指针 */
  184. bmpdt.showimg = rtgui_image_rotate(bmpdt.image, bmpdt.angle);
  185. if (bmpdt.showimg != RT_NULL)
  186. rtgui_widget_update(RTGUI_WIDGET(bmpdt.showbox));
  187. else
  188. return;
  189. if(bmpdt.showimg != bmpdt.image)
  190. {
  191. rtgui_image_destroy(bmpdt.showimg);
  192. bmpdt.showimg = RT_NULL;
  193. }
  194. }
  195. rtgui_container_t *demo_view_bmp(void)
  196. {
  197. rtgui_rect_t rect;
  198. rtgui_container_t *container, *showbox;
  199. rtgui_button_t *button;
  200. rtgui_textbox_t *box;
  201. /* 用bmpdt结构体记录一些参数 */
  202. rt_memset(&bmpdt, 0, sizeof(struct demo_bmp_dt));
  203. bmpdt.scale = 1.0;
  204. bmpdt.angle = 0.0;
  205. /* 创建用于演示本代码的容器控件 */
  206. container = demo_view("Bmp File:");
  207. demo_view_get_rect(container, &rect);
  208. rect.x1 += 85;
  209. rect.x2 -= 5;
  210. rect.y1 -= 42;
  211. rect.y2 = rect.y1 + 20;
  212. box = rtgui_textbox_create("", RTGUI_TEXTBOX_SINGLE);
  213. rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
  214. rtgui_container_add_child(container, RTGUI_WIDGET(box));
  215. bmpdt.box = box;
  216. /* create a button "open" */
  217. demo_view_get_rect(container, &rect);
  218. rect.x1 += 5;
  219. rect.x2 = rect.x1 + 60;
  220. rect.y1 -= 10;
  221. rect.y2 = rect.y1 + 24;
  222. button = rtgui_button_create("open");
  223. rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
  224. rtgui_container_add_child(container, RTGUI_WIDGET(button));
  225. rtgui_button_set_onbutton(button, demo_bitmap_open);
  226. /* create a button "zoom in" */
  227. demo_view_get_rect(container, &rect);
  228. rect.x1 += 85;
  229. rect.x2 = rect.x1 + 70;
  230. rect.y1 -= 10;
  231. rect.y2 = rect.y1 + 24;
  232. button = rtgui_button_create("zoom in");
  233. rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
  234. rtgui_container_add_child(container, RTGUI_WIDGET(button));
  235. rtgui_button_set_onbutton(button, demo_image_zoom_in);
  236. /* create a button "zoom out" */
  237. demo_view_get_rect(container, &rect);
  238. rect.x1 += 165;
  239. rect.x2 = rect.x1 + 70;
  240. rect.y1 -= 10;
  241. rect.y2 = rect.y1 + 24;
  242. button = rtgui_button_create("zoom out");
  243. rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
  244. rtgui_container_add_child(container, RTGUI_WIDGET(button));
  245. rtgui_button_set_onbutton(button, demo_image_zoom_out);
  246. /* create a button "rotate" */
  247. demo_view_get_rect(container, &rect);
  248. rect.x1 += 245;
  249. rect.x2 = rect.x1 + 70;
  250. rect.y1 -= 10;
  251. rect.y2 = rect.y1 + 24;
  252. button = rtgui_button_create("rotate");
  253. rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
  254. rtgui_container_add_child(container, RTGUI_WIDGET(button));
  255. rtgui_button_set_onbutton(button, demo_image_rotate);
  256. /* create a container "showbox" */
  257. demo_view_get_rect(container, &rect);
  258. rect.x1 += 5;
  259. rect.x2 -= 5;
  260. rect.y1 += 20;
  261. rect.y2 -= 0;
  262. showbox = rtgui_container_create();
  263. rtgui_widget_set_rect(RTGUI_WIDGET(showbox), &rect);
  264. rtgui_container_add_child(container, RTGUI_WIDGET(showbox));
  265. rtgui_widget_set_border(RTGUI_WIDGET(showbox), RTGUI_BORDER_SIMPLE);
  266. bmpdt.showbox = showbox;
  267. rtgui_object_set_event_handler(RTGUI_OBJECT(showbox), demo_bitmap_showbox);
  268. rtgui_widget_get_rect(RTGUI_WIDGET(showbox), &bmpdt.lastrect);
  269. rtgui_rect_inflate(&bmpdt.lastrect, -RTGUI_WIDGET_BORDER(showbox));
  270. return container;
  271. }
  272. #endif