CRotateImage.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. #include <string>
  2. #include "CRotateImage.h"
  3. #include "psram.h"
  4. static const char *TAG = "C ROTATE IMG";
  5. CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_temp, bool _flip) : CImageBasis(_name)
  6. {
  7. rgb_image = _org->rgb_image;
  8. channels = _org->channels;
  9. width = _org->width;
  10. height = _org->height;
  11. bpp = _org->bpp;
  12. externalImage = true;
  13. ImageTMP = _temp;
  14. ImageOrg = _org;
  15. islocked = false;
  16. doflip = _flip;
  17. }
  18. void CRotateImage::Mirror(){
  19. int memsize = width * height * channels;
  20. uint8_t* odata;
  21. if (ImageTMP)
  22. {
  23. odata = ImageTMP->RGBImageLock();
  24. }
  25. else
  26. {
  27. odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
  28. }
  29. int x_source, y_source;
  30. stbi_uc* p_target;
  31. stbi_uc* p_source;
  32. RGBImageLock();
  33. for (int x = 0; x < width; ++x)
  34. for (int y = 0; y < height; ++y)
  35. {
  36. p_target = odata + (channels * (y * width + x));
  37. x_source = width - x;
  38. y_source = y;
  39. p_source = rgb_image + (channels * (y_source * width + x_source));
  40. for (int _channels = 0; _channels < channels; ++_channels)
  41. p_target[_channels] = p_source[_channels];
  42. }
  43. // memcpy(rgb_image, odata, memsize);
  44. memCopy(odata, rgb_image, memsize);
  45. if (!ImageTMP)
  46. free_psram_heap(std::string(TAG) + "->odata", odata);
  47. if (ImageTMP)
  48. ImageTMP->RGBImageRelease();
  49. RGBImageRelease();
  50. }
  51. void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
  52. {
  53. int org_width, org_height;
  54. float m[2][3];
  55. float x_center = _centerx;
  56. float y_center = _centery;
  57. _angle = _angle / 180 * M_PI;
  58. if (doflip)
  59. {
  60. org_width = width;
  61. org_height = height;
  62. height = org_width;
  63. width = org_height;
  64. x_center = x_center - (org_width/2) + (org_height/2);
  65. y_center = y_center + (org_width/2) - (org_height/2);
  66. if (ImageOrg)
  67. {
  68. ImageOrg->height = height;
  69. ImageOrg->width = width;
  70. }
  71. }
  72. else
  73. {
  74. org_width = width;
  75. org_height = height;
  76. }
  77. m[0][0] = cos(_angle);
  78. m[0][1] = sin(_angle);
  79. m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
  80. m[1][0] = -m[0][1];
  81. m[1][1] = m[0][0];
  82. m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
  83. if (doflip)
  84. {
  85. m[0][2] = m[0][2] + (org_width/2) - (org_height/2);
  86. m[1][2] = m[1][2] - (org_width/2) + (org_height/2);
  87. }
  88. int memsize = width * height * channels;
  89. uint8_t* odata;
  90. if (ImageTMP)
  91. {
  92. odata = ImageTMP->RGBImageLock();
  93. }
  94. else
  95. {
  96. odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
  97. }
  98. int x_source, y_source;
  99. stbi_uc* p_target;
  100. stbi_uc* p_source;
  101. RGBImageLock();
  102. for (int x = 0; x < width; ++x)
  103. for (int y = 0; y < height; ++y)
  104. {
  105. p_target = odata + (channels * (y * width + x));
  106. x_source = int(m[0][0] * x + m[0][1] * y);
  107. y_source = int(m[1][0] * x + m[1][1] * y);
  108. x_source += int(m[0][2]);
  109. y_source += int(m[1][2]);
  110. if ((x_source >= 0) && (x_source < org_width) && (y_source >= 0) && (y_source < org_height))
  111. {
  112. p_source = rgb_image + (channels * (y_source * org_width + x_source));
  113. for (int _channels = 0; _channels < channels; ++_channels)
  114. p_target[_channels] = p_source[_channels];
  115. }
  116. else
  117. {
  118. for (int _channels = 0; _channels < channels; ++_channels)
  119. p_target[_channels] = 255;
  120. }
  121. }
  122. // memcpy(rgb_image, odata, memsize);
  123. memCopy(odata, rgb_image, memsize);
  124. if (!ImageTMP)
  125. {
  126. free_psram_heap(std::string(TAG) + "->odata", odata);
  127. }
  128. if (ImageTMP)
  129. ImageTMP->RGBImageRelease();
  130. RGBImageRelease();
  131. }
  132. void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery)
  133. {
  134. int org_width, org_height;
  135. float m[2][3];
  136. float x_center = _centerx;
  137. float y_center = _centery;
  138. _angle = _angle / 180 * M_PI;
  139. if (doflip)
  140. {
  141. org_width = width;
  142. org_height = height;
  143. height = org_width;
  144. width = org_height;
  145. x_center = x_center - (org_width/2) + (org_height/2);
  146. y_center = y_center + (org_width/2) - (org_height/2);
  147. if (ImageOrg)
  148. {
  149. ImageOrg->height = height;
  150. ImageOrg->width = width;
  151. }
  152. }
  153. else
  154. {
  155. org_width = width;
  156. org_height = height;
  157. }
  158. m[0][0] = cos(_angle);
  159. m[0][1] = sin(_angle);
  160. m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
  161. m[1][0] = -m[0][1];
  162. m[1][1] = m[0][0];
  163. m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
  164. if (doflip)
  165. {
  166. m[0][2] = m[0][2] + (org_width/2) - (org_height/2);
  167. m[1][2] = m[1][2] - (org_width/2) + (org_height/2);
  168. }
  169. int memsize = width * height * channels;
  170. uint8_t* odata;
  171. if (ImageTMP)
  172. {
  173. odata = ImageTMP->RGBImageLock();
  174. }
  175. else
  176. {
  177. odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
  178. }
  179. int x_source_1, y_source_1, x_source_2, y_source_2;
  180. float x_source, y_source;
  181. float quad_ul, quad_ur, quad_ol, quad_or;
  182. stbi_uc* p_target;
  183. stbi_uc *p_source_ul, *p_source_ur, *p_source_ol, *p_source_or;
  184. RGBImageLock();
  185. for (int x = 0; x < width; ++x)
  186. for (int y = 0; y < height; ++y)
  187. {
  188. p_target = odata + (channels * (y * width + x));
  189. x_source = (m[0][0] * x + m[0][1] * y);
  190. y_source = (m[1][0] * x + m[1][1] * y);
  191. x_source += (m[0][2]);
  192. y_source += (m[1][2]);
  193. x_source_1 = (int)x_source;
  194. x_source_2 = x_source_1 + 1;
  195. y_source_1 = (int)y_source;
  196. y_source_2 = y_source_1 + 1;
  197. quad_ul = (x_source_2 - x_source) * (y_source_2 - y_source);
  198. quad_ur = (1- (x_source_2 - x_source)) * (y_source_2 - y_source);
  199. quad_or = (x_source_2 - x_source) * (1-(y_source_2 - y_source));
  200. quad_ol = (1- (x_source_2 - x_source)) * (1-(y_source_2 - y_source));
  201. if ((x_source_1 >= 0) && (x_source_2 < org_width) && (y_source_1 >= 0) && (y_source_2 < org_height))
  202. {
  203. p_source_ul = rgb_image + (channels * (y_source_1 * org_width + x_source_1));
  204. p_source_ur = rgb_image + (channels * (y_source_1 * org_width + x_source_2));
  205. p_source_or = rgb_image + (channels * (y_source_2 * org_width + x_source_1));
  206. p_source_ol = rgb_image + (channels * (y_source_2 * org_width + x_source_2));
  207. for (int _channels = 0; _channels < channels; ++_channels)
  208. {
  209. p_target[_channels] = (int)((float)p_source_ul[_channels] * quad_ul
  210. + (float)p_source_ur[_channels] * quad_ur
  211. + (float)p_source_or[_channels] * quad_or
  212. + (float)p_source_ol[_channels] * quad_ol);
  213. }
  214. }
  215. else
  216. {
  217. for (int _channels = 0; _channels < channels; ++_channels)
  218. p_target[_channels] = 255;
  219. }
  220. }
  221. // memcpy(rgb_image, odata, memsize);
  222. memCopy(odata, rgb_image, memsize);
  223. if (!ImageTMP)
  224. {
  225. free_psram_heap(std::string(TAG) + "->odata", odata);
  226. }
  227. if (ImageTMP)
  228. ImageTMP->RGBImageRelease();
  229. RGBImageRelease();
  230. }
  231. void CRotateImage::Rotate(float _angle)
  232. {
  233. // ESP_LOGD(TAG, "width %d, height %d", width, height);
  234. Rotate(_angle, width / 2, height / 2);
  235. }
  236. void CRotateImage::RotateAntiAliasing(float _angle)
  237. {
  238. // ESP_LOGD(TAG, "width %d, height %d", width, height);
  239. RotateAntiAliasing(_angle, width / 2, height / 2);
  240. }
  241. void CRotateImage::Translate(int _dx, int _dy)
  242. {
  243. int memsize = width * height * channels;
  244. uint8_t* odata;
  245. if (ImageTMP)
  246. {
  247. odata = ImageTMP->RGBImageLock();
  248. }
  249. else
  250. {
  251. odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
  252. }
  253. int x_source, y_source;
  254. stbi_uc* p_target;
  255. stbi_uc* p_source;
  256. RGBImageLock();
  257. for (int x = 0; x < width; ++x)
  258. for (int y = 0; y < height; ++y)
  259. {
  260. p_target = odata + (channels * (y * width + x));
  261. x_source = x - _dx;
  262. y_source = y - _dy;
  263. if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height))
  264. {
  265. p_source = rgb_image + (channels * (y_source * width + x_source));
  266. for (int _channels = 0; _channels < channels; ++_channels)
  267. p_target[_channels] = p_source[_channels];
  268. }
  269. else
  270. {
  271. for (int _channels = 0; _channels < channels; ++_channels)
  272. p_target[_channels] = 255;
  273. }
  274. }
  275. // memcpy(rgb_image, odata, memsize);
  276. memCopy(odata, rgb_image, memsize);
  277. if (!ImageTMP)
  278. {
  279. free_psram_heap(std::string(TAG) + "->odata", odata);
  280. }
  281. if (ImageTMP)
  282. {
  283. ImageTMP->RGBImageRelease();
  284. }
  285. RGBImageRelease();
  286. }