ImageAndLayout.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. package com.epson.cameracopy.printlayout;
  2. import android.os.Parcel;
  3. import android.os.Parcelable;
  4. import com.epson.cameracopy.alt.SimpleBmpMerger;
  5. import org.opencv.core.Core;
  6. import org.opencv.core.CvType;
  7. import org.opencv.core.Mat;
  8. import org.opencv.core.MatOfInt;
  9. import org.opencv.core.MatOfPoint2f;
  10. import org.opencv.core.Point;
  11. import org.opencv.core.Scalar;
  12. import org.opencv.core.Size;
  13. import org.opencv.imgcodecs.Imgcodecs;
  14. import org.opencv.imgproc.Imgproc;
  15. import java.io.File;
  16. import java.util.ArrayList;
  17. import java.util.Arrays;
  18. import java.util.LinkedList;
  19. import epson.print.Util.ImageFileUtil;
  20. import epson.print.Util.OpenCvHelper;
  21. public class ImageAndLayout implements Parcelable {
  22. static final /* synthetic */ boolean $assertionsDisabled = false;
  23. public static final Parcelable.Creator<ImageAndLayout> CREATOR = new Parcelable.Creator<ImageAndLayout>() {
  24. public ImageAndLayout createFromParcel(Parcel parcel) {
  25. return new ImageAndLayout(parcel);
  26. }
  27. public ImageAndLayout[] newArray(int i) {
  28. return new ImageAndLayout[i];
  29. }
  30. };
  31. private int mInterpolation;
  32. private boolean mIsPaperLandscape;
  33. private double mOffsetX;
  34. private double mOffsetY;
  35. private int mOpenCvExifRotation;
  36. private boolean mOpenCvExifRotationCancel;
  37. private String mOrgFilename;
  38. private double mPrintTargetHeight;
  39. private double mPrintTargetWidth;
  40. private int mPrintableAreaHeight;
  41. private int mPrintableAreaWidth;
  42. private int mRotation;
  43. public int describeContents() {
  44. return 0;
  45. }
  46. static {
  47. System.loadLibrary("opencv_java3");
  48. }
  49. public ImageAndLayout() {
  50. mInterpolation = 2;
  51. mIsPaperLandscape = true;
  52. mOpenCvExifRotationCancel = true;
  53. }
  54. public void writeToParcel(Parcel parcel, int i) {
  55. parcel.writeInt(mPrintableAreaWidth);
  56. parcel.writeInt(mPrintableAreaHeight);
  57. parcel.writeString(mOrgFilename);
  58. parcel.writeDouble(mPrintTargetWidth);
  59. parcel.writeDouble(mPrintTargetHeight);
  60. parcel.writeDouble(mOffsetX);
  61. parcel.writeDouble(mOffsetY);
  62. parcel.writeInt(mRotation);
  63. parcel.writeBooleanArray(new boolean[]{mIsPaperLandscape});
  64. }
  65. private ImageAndLayout(Parcel parcel) {
  66. mInterpolation = 2;
  67. mPrintableAreaWidth = parcel.readInt();
  68. mPrintableAreaHeight = parcel.readInt();
  69. mOrgFilename = parcel.readString();
  70. mPrintTargetWidth = parcel.readDouble();
  71. mPrintTargetHeight = parcel.readDouble();
  72. mOffsetX = parcel.readDouble();
  73. mOffsetY = parcel.readDouble();
  74. mRotation = parcel.readInt();
  75. boolean[] zArr = new boolean[1];
  76. parcel.readBooleanArray(zArr);
  77. mIsPaperLandscape = zArr[0];
  78. mOpenCvExifRotationCancel = true;
  79. }
  80. public void setOpenCvExifRotationCancel(boolean z) {
  81. mOpenCvExifRotationCancel = z;
  82. }
  83. public void setLayoutAreaSize(int i, int i2) {
  84. mPrintableAreaWidth = i;
  85. mPrintableAreaHeight = i2;
  86. }
  87. public void setLayout(double d, double d2, double d3, double d4, int i) {
  88. mPrintTargetWidth = d;
  89. mPrintTargetHeight = d2;
  90. mOffsetX = d3;
  91. mOffsetY = d4;
  92. mRotation = i;
  93. }
  94. public void setPaperIsLandscape(boolean z) {
  95. mIsPaperLandscape = z;
  96. }
  97. public boolean isPaperLandscape() {
  98. return mIsPaperLandscape;
  99. }
  100. public void setOrgFileName(String str) {
  101. mOrgFilename = str;
  102. }
  103. public String getOrgFileName() {
  104. return mOrgFilename;
  105. }
  106. private double[] getExRate(int[] iArr) {
  107. int i;
  108. int i2;
  109. double[] dArr = {1.0d, 1.0d};
  110. if (iArr == null || iArr.length < 2 || (i = mPrintableAreaWidth) <= 0 || (i2 = mPrintableAreaHeight) <= 0) {
  111. return dArr;
  112. }
  113. dArr[0] = (iArr[0]) / (i);
  114. dArr[1] = (iArr[1]) / (i2);
  115. return dArr;
  116. }
  117. static Mat new3x2Mat(double d, double d2, double d3, double d4, double d5, double d6) {
  118. final double d7 = d;
  119. final double d8 = d2;
  120. final double d9 = d3;
  121. final double d10 = d4;
  122. final double d11 = d5;
  123. final double d12 = d6;
  124. return new Mat(2, 3, 6) {
  125. {
  126. put(0, 0, d7, d8, d9);
  127. put(1, 0, d10, d11, d12);
  128. }
  129. };
  130. }
  131. static Mat getTransformMat0(Size size, Size size2, double d, double d2, int i) {
  132. MatOfPoint2f matOfPoint2f;
  133. Size size3 = size;
  134. Size size4 = size2;
  135. double d3 = size3.width;
  136. double d4 = size3.height;
  137. MatOfPoint2f matOfPoint2f2 = new MatOfPoint2f(new Point(0.0d, 0.0d), new Point(0.0d, size4.height), new Point(size4.width, 0.0d));
  138. switch (i & 3) {
  139. case 1:
  140. double d5 = d3 + d;
  141. double d6 = d2 + 0.0d;
  142. matOfPoint2f = new MatOfPoint2f(new Point(d5, d6), new Point(d + 0.0d, d6), new Point(d5, d4 + d2));
  143. break;
  144. case 2:
  145. double d7 = d3 + d;
  146. double d8 = d4 + d2;
  147. matOfPoint2f = new MatOfPoint2f(new Point(d7, d8), new Point(d7, d2 + 0.0d), new Point(d + 0.0d, d8));
  148. break;
  149. case 3:
  150. double d9 = d + 0.0d;
  151. double d10 = d4 + d2;
  152. matOfPoint2f = new MatOfPoint2f(new Point(d9, d10), new Point(d3 + d, d10), new Point(d9, d2 + 0.0d));
  153. break;
  154. default:
  155. double d11 = d + 0.0d;
  156. double d12 = d2 + 0.0d;
  157. matOfPoint2f = new MatOfPoint2f(new Point(d11, d12), new Point(d11, d4 + d2), new Point(d3 + d, d12));
  158. break;
  159. }
  160. Mat affineTransform = Imgproc.getAffineTransform(matOfPoint2f2, matOfPoint2f);
  161. matOfPoint2f2.release();
  162. matOfPoint2f.release();
  163. return affineTransform;
  164. }
  165. static Mat getTransformMat1(Size size, Size size2, double d, double d2, int i) {
  166. MatOfPoint2f matOfPoint2f;
  167. Size size3 = size;
  168. Size size4 = size2;
  169. double d3 = size3.width;
  170. double d4 = size3.height;
  171. double d5 = size3.width;
  172. double d6 = size4.width;
  173. double d7 = size3.height;
  174. double d8 = size4.height;
  175. MatOfPoint2f matOfPoint2f2 = new MatOfPoint2f(new Point(0.0d, 0.0d), new Point(0.0d, size4.height), new Point(size4.width, 0.0d));
  176. switch (i & 3) {
  177. case 1:
  178. double d9 = d3 + d;
  179. double d10 = d2 + 0.0d;
  180. matOfPoint2f = new MatOfPoint2f(new Point(d9, d10), new Point(d + 0.0d, d10), new Point(d9, d4 + d2));
  181. break;
  182. case 2:
  183. double d11 = d3 + d;
  184. double d12 = d4 + d2;
  185. matOfPoint2f = new MatOfPoint2f(new Point(d11, d12), new Point(d11, d2 + 0.0d), new Point(d + 0.0d, d12));
  186. break;
  187. case 3:
  188. double d13 = d + 0.0d;
  189. double d14 = d4 + d2;
  190. matOfPoint2f = new MatOfPoint2f(new Point(d13, d14), new Point(d3 + d, d14), new Point(d13, d2 + 0.0d));
  191. break;
  192. default:
  193. double d15 = d + 0.0d;
  194. double d16 = d2 + 0.0d;
  195. matOfPoint2f = new MatOfPoint2f(new Point(d15, d16), new Point(d15, d4 + d2), new Point(d3 + d, d16));
  196. break;
  197. }
  198. Mat affineTransform = Imgproc.getAffineTransform(matOfPoint2f2, matOfPoint2f);
  199. matOfPoint2f2.release();
  200. matOfPoint2f.release();
  201. return affineTransform;
  202. }
  203. static Mat getTransformMat(Size size, Size size2, double d, double d2, int i) {
  204. double d3;
  205. double d4;
  206. Size size3 = size;
  207. Size size4 = size2;
  208. if ((i & 1) == 0) {
  209. double d5 = size3.width / size4.width;
  210. d4 = size3.height / size4.height;
  211. d3 = d5;
  212. } else {
  213. double d6 = size3.width / size4.height;
  214. d4 = size3.height / size4.width;
  215. d3 = d6;
  216. }
  217. int i2 = (d3 / 2.0d);
  218. int i3 = (d4 / 2.0d);
  219. switch (i & 3) {
  220. case 1:
  221. return new3x2Mat(0.0d, -d3, ((d + size3.width) - (i2)) - 1.0d, d4, 0.0d, d2 + (i3));
  222. case 2:
  223. return new3x2Mat(-d3, 0.0d, ((d + size3.width) - (i2)) - 1.0d, 0.0d, -d4, ((d2 + size3.height) - (i3)) - 1.0d);
  224. case 3:
  225. return new3x2Mat(0.0d, d3, d + (i2), -d4, 0.0d, ((d2 + size3.height) - (i3)) - 1.0d);
  226. default:
  227. return new3x2Mat(d3, 0.0d, d + (i2), 0.0d, d4, d2 + (i3));
  228. }
  229. }
  230. private Size getPrintImageSize(double[] dArr) {
  231. return new Size(mPrintTargetWidth * dArr[0], mPrintTargetHeight * dArr[1]);
  232. }
  233. private Mat getPrintMat(int[] iArr, int i, Mat mat) {
  234. switch (i & 3) {
  235. case 1:
  236. Mat mat2 = new Mat(2, 3, 6);
  237. mat2.put(0, 0, mat.get(1, 0)[0] * -1.0d);
  238. mat2.put(0, 1, mat.get(1, 1)[0] * -1.0d);
  239. mat2.put(0, 2, (mat.get(1, 2)[0] * -1.0d) + (iArr[0]));
  240. mat2.put(1, 0, mat.get(0, 0)[0]);
  241. mat2.put(1, 1, mat.get(0, 1)[0]);
  242. mat2.put(1, 2, mat.get(0, 2)[0]);
  243. return mat2;
  244. case 2:
  245. Mat mat3 = null;
  246. mat3.put(0, 0, mat.get(0, 0)[0] * -1.0d);
  247. mat3.put(0, 1, mat.get(0, 1)[0] * -1.0d);
  248. mat3.put(0, 2, (mat.get(0, 2)[0] * -1.0d) + (iArr[0]));
  249. mat3.put(1, 0, mat.get(1, 0)[0] * -1.0d);
  250. mat3.put(1, 1, mat.get(1, 1)[0] * -1.0d);
  251. mat3.put(1, 2, (mat.get(1, 2)[0] * -1.0d) + (iArr[1]));
  252. return mat3;
  253. case 3:
  254. Mat mat4 = new Mat(2, 3, 6);
  255. mat4.put(0, 0, mat.get(1, 0)[0]);
  256. mat4.put(0, 1, mat.get(1, 1)[0]);
  257. mat4.put(0, 2, mat.get(1, 2)[0] + (iArr[0]));
  258. mat4.put(1, 0, mat.get(0, 0)[0] * -1.0d);
  259. mat4.put(1, 1, mat.get(0, 1)[0] * -1.0d);
  260. mat4.put(1, 2, mat.get(0, 2)[0] * -1.0d);
  261. return mat4;
  262. default:
  263. return mat.clone();
  264. }
  265. }
  266. public Mat makePrintImageMat(Mat mat, int i, int[] iArr) {
  267. Mat transMat = getTransMat(mat, i, iArr);
  268. Mat mat2 = new Mat(iArr[1], iArr[0], mat.type());
  269. Imgproc.warpAffine(mat, mat2, transMat, mat2.size(), mInterpolation, 0, new Scalar(255.0d, 255.0d, 255.0d, 255.0d));
  270. transMat.release();
  271. return mat2;
  272. }
  273. private Mat getTransMat(Mat mat, int i, int[] iArr) {
  274. int[] iArr2 = new int[2];
  275. if ((i & 1) != 0) {
  276. iArr2[0] = iArr[1];
  277. iArr2[1] = iArr[0];
  278. } else {
  279. iArr2[0] = iArr[0];
  280. iArr2[1] = iArr[1];
  281. }
  282. double[] exRate = getExRate(iArr2);
  283. Size printImageSize = getPrintImageSize(exRate);
  284. double d = mOffsetX * exRate[0];
  285. double d2 = mOffsetY;
  286. int imageRotation = getImageRotation(mRotation);
  287. Mat transformMat = getTransformMat(printImageSize, mat.size(), d, exRate[1] * d2, imageRotation);
  288. Mat printMat = getPrintMat(iArr, i, transformMat);
  289. transformMat.release();
  290. return printMat;
  291. }
  292. private boolean affineBand(Mat mat, Mat mat2, int i, int i2, int i3, File file) {
  293. Mat clone = mat2.clone();
  294. Mat mat3 = new Mat();
  295. Size size = new Size(i, i2);
  296. clone.put(1, 2, clone.get(1, 2)[0] - (i3));
  297. Mat mat4 = null;
  298. try {
  299. Imgproc.warpAffine(mat, mat3, clone, size, mInterpolation, 0, new Scalar(255.0d, 255.0d, 255.0d, 255.0d));
  300. if (mat.type() == CvType.CV_8UC1) {
  301. mat4 = make24BitMatFromGrayMat(mat3);
  302. if (!Imgcodecs.imwrite(file.toString(), mat4)) {
  303. clone.release();
  304. mat3.release();
  305. if (mat4 != null) {
  306. mat4.release();
  307. }
  308. return false;
  309. }
  310. } else if (!Imgcodecs.imwrite(file.toString(), mat3)) {
  311. clone.release();
  312. mat3.release();
  313. return false;
  314. }
  315. clone.release();
  316. mat3.release();
  317. if (mat4 != null) {
  318. mat4.release();
  319. }
  320. return true;
  321. } catch (Exception unused) {
  322. clone.release();
  323. mat3.release();
  324. if (mat4 != null) {
  325. mat4.release();
  326. }
  327. return false;
  328. } catch (Throwable th) {
  329. clone.release();
  330. mat3.release();
  331. if (mat4 != null) {
  332. mat4.release();
  333. }
  334. throw th;
  335. }
  336. }
  337. private boolean makeBandImageFile(Mat mat, int i, int[] iArr, String str, LinkedList<File> linkedList) {
  338. String str2 = str;
  339. LinkedList<File> linkedList2 = linkedList;
  340. Mat transMat = getTransMat(mat, i, iArr);
  341. int i2 = 0;
  342. int i3 = 0;
  343. while (true) {
  344. int i4 = i2 + 512;
  345. if (i4 < iArr[1]) {
  346. File file = new File(str2, "bo" + i3 + ".bmp");
  347. affineBand(mat, transMat, iArr[0], 512, i2, file);
  348. if (!file.exists()) {
  349. return false;
  350. }
  351. linkedList2.addFirst(file);
  352. i3++;
  353. i2 = i4;
  354. } else {
  355. File file2 = new File(str2, "bo" + i3 + ".bmp");
  356. if (!affineBand(mat, transMat, iArr[0], iArr[1] - i2, i2, file2)) {
  357. return false;
  358. }
  359. linkedList2.addFirst(file2);
  360. return true;
  361. }
  362. }
  363. }
  364. private boolean makePrintImageFile(Mat mat, int i, int[] iArr, String str) {
  365. String parent = new File(str).getParent();
  366. LinkedList linkedList = new LinkedList();
  367. if (makeBandImageFile(mat, i, iArr, parent, linkedList) && SimpleBmpMerger.margeBmpFile(str, linkedList.iterator())) {
  368. return true;
  369. }
  370. return false;
  371. }
  372. private Mat make24BitMatFromGrayMat(Mat mat) {
  373. Mat mat2 = new Mat(mat.height(), mat.width(), CvType.CV_8UC3);
  374. Core.mixChannels(Arrays.asList(new Mat[]{mat}), Arrays.asList(new Mat[]{mat2}), new MatOfInt(0, 0, 0, 1, 0, 2));
  375. return mat2;
  376. }
  377. public boolean createPrintData(String str, boolean z, int[] iArr, int i) {
  378. Mat mat = null;
  379. try {
  380. setOpenCvJpegRotation(mOrgFilename);
  381. Mat imread = Imgcodecs.imread(mOrgFilename, -1);
  382. mat = imread.channels() == 4 ? convertRgbaToRgbTrWhite(imread) : imread;
  383. if (z) {
  384. int channels = mat.channels();
  385. if (channels != 1) {
  386. if (channels != 3) {
  387. if (mat != null) {
  388. mat.release();
  389. }
  390. File file = new File(str);
  391. if (file.exists()) {
  392. file.delete();
  393. }
  394. return false;
  395. }
  396. Imgproc.cvtColor(mat, mat, 7);
  397. Imgproc.cvtColor(mat, mat, 8, 3);
  398. }
  399. }
  400. boolean makePrintImageFile = makePrintImageFile(mat, i, iArr, str);
  401. if (mat != null) {
  402. mat.release();
  403. }
  404. if (!makePrintImageFile) {
  405. File file2 = new File(str);
  406. if (file2.exists()) {
  407. file2.delete();
  408. }
  409. }
  410. return makePrintImageFile;
  411. } catch (OutOfMemoryError unused) {
  412. if (mat != null) {
  413. mat.release();
  414. }
  415. File file3 = new File(str);
  416. if (file3.exists()) {
  417. file3.delete();
  418. }
  419. return false;
  420. } catch (Exception unused2) {
  421. if (mat != null) {
  422. mat.release();
  423. }
  424. File file4 = new File(str);
  425. if (file4.exists()) {
  426. file4.delete();
  427. }
  428. return false;
  429. } catch (Throwable th) {
  430. if (mat != null) {
  431. mat.release();
  432. }
  433. File file5 = new File(str);
  434. if (file5.exists()) {
  435. file5.delete();
  436. }
  437. throw th;
  438. }
  439. }
  440. @VisibleForTesting
  441. static Mat calc255Alpha(Mat mat) {
  442. Mat mat2 = new Mat();
  443. Core.multiply(mat, new Scalar(-255.0d), mat2);
  444. Mat mat3 = new Mat();
  445. Core.add(mat2, new Scalar(255.0d), mat3);
  446. mat2.release();
  447. return mat3;
  448. }
  449. @VisibleForTesting
  450. @NonNull
  451. static Mat convertRgbaToRgbTrWhite(Mat mat) {
  452. ArrayList arrayList = new ArrayList();
  453. Core.split(mat, arrayList);
  454. mat.release();
  455. Mat mat2 = new Mat();
  456. ((Mat) arrayList.get(3)).convertTo(mat2, CvType.CV_32FC1, 0.00392156862745098d);
  457. ((Mat) arrayList.get(3)).release();
  458. arrayList.remove(3);
  459. ArrayList arrayList2 = new ArrayList();
  460. for (int i = 0; i < 3; i++) {
  461. arrayList2.add(mat2);
  462. }
  463. Mat mat3 = new Mat();
  464. Core.merge(arrayList2, mat3);
  465. Mat mat4 = new Mat();
  466. Mat mat5 = new Mat();
  467. Core.merge(arrayList, mat4);
  468. ((Mat) arrayList.get(0)).release();
  469. ((Mat) arrayList.get(1)).release();
  470. ((Mat) arrayList.get(2)).release();
  471. mat4.convertTo(mat5, CvType.CV_32FC1);
  472. mat4.release();
  473. Mat mul = mat5.mul(mat3);
  474. mat5.release();
  475. Mat mat6 = new Mat();
  476. mul.convertTo(mat6, CvType.CV_8UC3);
  477. mul.release();
  478. Mat calc255Alpha = calc255Alpha(mat2);
  479. Mat mat7 = new Mat();
  480. calc255Alpha.convertTo(mat7, CvType.CV_8UC1);
  481. Mat mat8 = new Mat();
  482. Imgproc.cvtColor(mat7, mat8, 8, 3);
  483. Core.add(mat6, mat8, mat6);
  484. return mat6;
  485. }
  486. @NonNull
  487. private static Mat convertRgbaToRgb(Mat mat) {
  488. ArrayList arrayList = new ArrayList();
  489. Core.split(mat, arrayList);
  490. mat.release();
  491. Mat mat2 = new Mat();
  492. ((Mat) arrayList.get(3)).convertTo(mat2, CvType.CV_32FC1, 0.00392156862745098d);
  493. ((Mat) arrayList.get(3)).release();
  494. arrayList.remove(3);
  495. ArrayList arrayList2 = new ArrayList();
  496. for (int i = 0; i < 3; i++) {
  497. arrayList2.add(mat2);
  498. }
  499. Mat mat3 = new Mat();
  500. Core.merge(arrayList2, mat3);
  501. mat2.release();
  502. Mat mat4 = new Mat();
  503. Mat mat5 = new Mat();
  504. Core.merge(arrayList, mat4);
  505. ((Mat) arrayList.get(0)).release();
  506. ((Mat) arrayList.get(1)).release();
  507. ((Mat) arrayList.get(2)).release();
  508. mat4.convertTo(mat5, CvType.CV_32FC1);
  509. mat4.release();
  510. Mat mul = mat5.mul(mat3);
  511. mat5.release();
  512. Mat mat6 = new Mat();
  513. mul.convertTo(mat6, CvType.CV_8UC3);
  514. mul.release();
  515. return mat6;
  516. }
  517. private void setOpenCvJpegRotation(String str) {
  518. mOpenCvExifRotation = 0;
  519. if (OpenCvHelper.doseImreadRotateWithExifTag()) {
  520. mOpenCvExifRotation = ImageFileUtil.getExifRotationDegree(str);
  521. if (mOpenCvExifRotation < 0) {
  522. mOpenCvExifRotation = 0;
  523. }
  524. }
  525. }
  526. private int getImageRotation(int i) {
  527. if (mOpenCvExifRotationCancel) {
  528. i -= mOpenCvExifRotation;
  529. }
  530. if (i < 0) {
  531. i += (((-i) / 4) + 1) * 4;
  532. }
  533. return i % 4;
  534. }
  535. private void setInterpolation(int i) {
  536. mInterpolation = i;
  537. }
  538. }