You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

imreadwrite.cpp 5.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
  4. //
  5. // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // https://opensource.org/licenses/BSD-3-Clause
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #include "imreadwrite.h"
  15. #include <stdio.h>
  16. #define STB_IMAGE_IMPLEMENTATION
  17. #define STBI_NO_THREAD_LOCALS
  18. #define STBI_ONLY_JPEG
  19. #define STBI_ONLY_PNG
  20. #define STBI_ONLY_BMP
  21. #define STBI_ONLY_PNM
  22. #include "../../src/stb_image.h"
  23. #define STB_IMAGE_WRITE_IMPLEMENTATION
  24. #include "../../src/stb_image_write.h"
  25. namespace cv {
  26. Mat imread(const std::string& path, int flags)
  27. {
  28. int desired_channels = 0;
  29. if (flags == IMREAD_UNCHANGED)
  30. {
  31. desired_channels = 0;
  32. }
  33. else if (flags == IMREAD_GRAYSCALE)
  34. {
  35. desired_channels = 1;
  36. }
  37. else if (flags == IMREAD_COLOR)
  38. {
  39. desired_channels = 3;
  40. }
  41. else
  42. {
  43. // unknown flags
  44. return Mat();
  45. }
  46. int w;
  47. int h;
  48. int c;
  49. unsigned char* pixeldata = stbi_load(path.c_str(), &w, &h, &c, desired_channels);
  50. if (!pixeldata)
  51. {
  52. // load failed
  53. return Mat();
  54. }
  55. if (desired_channels)
  56. {
  57. c = desired_channels;
  58. }
  59. // copy pixeldata to Mat
  60. Mat img;
  61. if (c == 1)
  62. {
  63. img.create(h, w, CV_8UC1);
  64. }
  65. else if (c == 3)
  66. {
  67. img.create(h, w, CV_8UC3);
  68. }
  69. else if (c == 4)
  70. {
  71. img.create(h, w, CV_8UC4);
  72. }
  73. else
  74. {
  75. // unexpected channels
  76. stbi_image_free(pixeldata);
  77. return Mat();
  78. }
  79. memcpy(img.data, pixeldata, static_cast<size_t>(w) * static_cast<size_t>(h) * static_cast<size_t>(c));
  80. stbi_image_free(pixeldata);
  81. // // resolve exif orientation
  82. // {
  83. // std::ifstream ifs;
  84. // ifs.open(filename.c_str(), std::ifstream::in);
  85. //
  86. // if (ifs.good())
  87. // {
  88. // ExifReader exif_reader(ifs);
  89. // if (exif_reader.parse())
  90. // {
  91. // ExifEntry_t e = exif_reader.getTag(ORIENTATION);
  92. // int orientation = e.field_u16;
  93. // if (orientation >= 1 && orientation <= 8)
  94. // rotate_by_orientation(img, img, orientation);
  95. // }
  96. // }
  97. //
  98. // ifs.close();
  99. // }
  100. // rgb to bgr
  101. if (c == 3)
  102. {
  103. uchar* p = img.data;
  104. for (int i = 0; i < w * h; i++)
  105. {
  106. std::swap(p[0], p[2]);
  107. p += 3;
  108. }
  109. }
  110. if (c == 4)
  111. {
  112. uchar* p = img.data;
  113. for (int i = 0; i < w * h; i++)
  114. {
  115. std::swap(p[0], p[2]);
  116. p += 4;
  117. }
  118. }
  119. return img;
  120. }
  121. bool imwrite(const std::string& path, const Mat& m, const std::vector<int>& params)
  122. {
  123. const char* _ext = strrchr(path.c_str(), '.');
  124. if (!_ext)
  125. {
  126. // missing extension
  127. return false;
  128. }
  129. std::string ext = _ext;
  130. Mat img = m.clone();
  131. // bgr to rgb
  132. int c = 0;
  133. if (img.type() == CV_8UC1)
  134. {
  135. c = 1;
  136. }
  137. else if (img.type() == CV_8UC3)
  138. {
  139. c = 3;
  140. uchar* p = img.data;
  141. for (int i = 0; i < img.cols * img.rows; i++)
  142. {
  143. std::swap(p[0], p[2]);
  144. p += 3;
  145. }
  146. }
  147. else if (img.type() == CV_8UC4)
  148. {
  149. c = 4;
  150. uchar* p = img.data;
  151. for (int i = 0; i < img.cols * img.rows; i++)
  152. {
  153. std::swap(p[0], p[2]);
  154. p += 4;
  155. }
  156. }
  157. else
  158. {
  159. // unexpected image channels
  160. return false;
  161. }
  162. bool success = false;
  163. if (ext == ".jpg" || ext == ".jpeg" || ext == ".JPG" || ext == ".JPEG")
  164. {
  165. int quality = 95;
  166. for (size_t i = 0; i < params.size(); i += 2)
  167. {
  168. if (params[i] == IMWRITE_JPEG_QUALITY)
  169. {
  170. quality = params[i + 1];
  171. break;
  172. }
  173. }
  174. success = stbi_write_jpg(path.c_str(), img.cols, img.rows, c, img.data, quality);
  175. }
  176. else if (ext == ".png" || ext == ".PNG")
  177. {
  178. success = stbi_write_png(path.c_str(), img.cols, img.rows, c, img.data, 0);
  179. }
  180. else if (ext == ".bmp" || ext == ".BMP")
  181. {
  182. success = stbi_write_bmp(path.c_str(), img.cols, img.rows, c, img.data);
  183. }
  184. else
  185. {
  186. // unknown extension type
  187. return false;
  188. }
  189. return success;
  190. }
  191. } // namespace cv