{"id":1092,"date":"2025-10-13T04:26:05","date_gmt":"2025-10-12T20:26:05","guid":{"rendered":"https:\/\/vm1.go2see.me\/?p=1092"},"modified":"2025-10-13T04:49:28","modified_gmt":"2025-10-12T20:49:28","slug":"java-lab6-10-13","status":"publish","type":"post","link":"https:\/\/vm1.go2see.me\/?p=1092","title":{"rendered":"Java LAB6 10-13"},"content":{"rendered":"<p>\u4ee5\u4e0b\u662f\u4f60\u63d0\u4f9b\u7684\u6a21\u7d44\u540d\u7a31\u7684\u4e2d\u6587\u89e3\u91cb\uff0c\u5047\u8a2d\u9019\u662f\u4e00\u500b\u5f71\u50cf\u8655\u7406\u76f8\u95dc\u7684\u8edf\u9ad4\u67b6\u69cb\uff1a<\/p>\n<h3>\ud83d\udce6 \u6a21\u7d44\u540d\u7a31\u8207\u4e2d\u6587\u8aaa\u660e<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u6a21\u7d44\u540d\u7a31<\/th>\n<th>\u4e2d\u6587\u8aaa\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>DoubleMatrix<\/code><\/td>\n<td>\u96d9\u7cbe\u5ea6\u77e9\u9663\u8655\u7406\u6a21\u7d44\uff0c\u7528\u65bc\u5f71\u50cf\u6ffe\u6ce2\u3001\u5085\u7acb\u8449\u8f49\u63db\u7b49\u6578\u503c\u904b\u7b97<\/td>\n<\/tr>\n<tr>\n<td><code>Image<\/code><\/td>\n<td>\u5f71\u50cf\u8cc7\u6599\u7d50\u69cb\uff0c\u53ef\u80fd\u5305\u542b\u50cf\u7d20\u9663\u5217\u3001\u89e3\u6790\u5ea6\u3001\u8272\u5f69\u683c\u5f0f\u7b49\u8cc7\u8a0a<\/td>\n<\/tr>\n<tr>\n<td><code>Rectangle<\/code><\/td>\n<td>\u77e9\u5f62\u5340\u57df\u5b9a\u7fa9\uff0c\u7528\u65bc\u6a19\u8a18ROI\uff08\u611f\u8208\u8da3\u5340\u57df\uff09\u3001\u88c1\u526a\u7bc4\u570d\u6216\u7269\u4ef6\u908a\u754c<\/td>\n<\/tr>\n<tr>\n<td><code>DFTOutput<\/code><\/td>\n<td>\u5085\u7acb\u8449\u8f49\u63db\u7d50\u679c\u5132\u5b58\u6a21\u7d44\uff0c\u53ef\u80fd\u5305\u542b\u983b\u8b5c\u7684\u5e45\u503c\u3001\u76f8\u4f4d\u7b49<\/td>\n<\/tr>\n<tr>\n<td><code>ImageProcessing<\/code><\/td>\n<td>\u5f71\u50cf\u8655\u7406\u6838\u5fc3\u6a21\u7d44\uff0c\u57f7\u884c\u6ffe\u6ce2\u3001\u908a\u7de3\u5075\u6e2c\u3001\u92b3\u5316\u7b49\u6f14\u7b97\u6cd5<\/td>\n<\/tr>\n<tr>\n<td><code>ImageTransformer<\/code><\/td>\n<td>\u5f71\u50cf\u5e7e\u4f55\u6216\u8272\u5f69\u8f49\u63db\u6a21\u7d44\uff0c\u4f8b\u5982\u65cb\u8f49\u3001\u7e2e\u653e\u3001\u7070\u968e\u8f49\u63db\u7b49<\/td>\n<\/tr>\n<tr>\n<td><code>Task1test<\/code><\/td>\n<td>\u4efb\u52d9\u4e00\u7684\u6e2c\u8a66\u6a21\u7d44\uff0c\u7528\u65bc\u9a57\u8b49\u7279\u5b9a\u6f14\u7b97\u6cd5\u6216\u529f\u80fd\u662f\u5426\u6b63\u78ba<\/td>\n<\/tr>\n<tr>\n<td><code>Task2test<\/code><\/td>\n<td>\u4efb\u52d9\u4e8c\u7684\u6e2c\u8a66\u6a21\u7d44\uff0c\u53ef\u80fd\u91dd\u5c0d\u5085\u7acb\u8449\u8f49\u63db\u6216\u5f71\u50cf\u8f49\u63db\u9032\u884c\u9a57\u8b49<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u9019\u6a23\u7684\u67b6\u69cb\u770b\u8d77\u4f86\u975e\u5e38\u6a21\u7d44\u5316\uff0c\u9069\u5408\u9032\u884c\u5f71\u50cf\u8655\u7406\u7684\u6559\u5b78\u3001\u5c55\u793a\u6216\u5de5\u7a0b\u5c08\u6848\u3002\u5982\u679c\u4f60\u6b63\u5728\u8a2d\u8a08\u4e00\u500b\u5c55\u793a\u7528\u7684\u7cfb\u7d71\uff0c\u6211\u53ef\u4ee5\u5e6b\u4f60\u88dc\u4e0a README \u6587\u4ef6\u3001\u6a21\u64ec\u8173\u672c\u3001\u6216\u662f\u4e2d\u82f1\u6587\u8a3b\u89e3\u7684\u7a0b\u5f0f\u78bc\u3002\u4f60\u60f3\u91dd\u5c0d\u54ea\u500b\u6a21\u7d44\u6df1\u5165\u6574\u7406\u6216\u512a\u5316\u5462\uff1f<\/p>\n<h2>1 DoubleMatrix<\/h2>\n<blockquote>\n<p><strong>DoubleMatrix<\/strong><\/p>\n<p>\u9019\u6bb5 Java \u7a0b\u5f0f\u78bc\u5b9a\u7fa9\u4e86\u4e00\u500b\u4e0d\u53ef\u8b8a\u7684 <code>DoubleMatrix<\/code> \u985e\u5225\uff0c\u7528\u4f86\u8868\u793a\u96d9\u7cbe\u5ea6\u6d6e\u9ede\u6578\u7684\u77e9\u9663\u3002\u4ee5\u4e0b\u662f\u4e2d\u6587\u89e3\u91cb\u8207\u7d50\u69cb\u5206\u6790\uff1a<\/p>\n<h3>\ud83d\udcd8 \u985e\u5225\u8aaa\u660e\uff1a<code>DoubleMatrix<\/code><\/h3>\n<p>\u9019\u662f\u4e00\u500b\u7528\u4f86\u8868\u793a <code>double<\/code> \u985e\u578b\u7684\u4e8c\u7dad\u77e9\u9663\u7684\u8cc7\u6599\u7d50\u69cb\uff0c\u8a2d\u8a08\u4e0a\u5f37\u8abf\uff1a<\/p>\n<ul>\n<li>\n<p><strong>\u4e0d\u53ef\u8b8a\u6027<\/strong>\uff08<code>final<\/code> \u985e\u5225\uff09<\/p>\n<\/li>\n<li>\n<p><strong>\u6578\u503c\u7cbe\u5ea6\u6bd4\u8f03<\/strong>\uff08\u4f7f\u7528 <code>epsilon = 1e-7<\/code>\uff09<\/p>\n<\/li>\n<li>\n<p><strong>\u8cc7\u6599\u5b8c\u6574\u6027\u4fdd\u8b49<\/strong>\uff08\u900f\u904e\u8868\u793a\u4e0d\u8b8a\u5f0f\uff09<\/p>\n<h3>\ud83e\udde9 \u985e\u5225\u6210\u54e1\u8207\u529f\u80fd<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u6210\u54e1\/\u65b9\u6cd5<\/th>\n<th>\u4e2d\u6587\u8aaa\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>epsilon<\/code><\/td>\n<td>\u6bd4\u8f03\u5169\u500b\u77e9\u9663\u662f\u5426\u76f8\u7b49\u6642\u4f7f\u7528\u7684\u8aa4\u5dee\u5bb9\u5fcd\u503c\uff0810\u207b\u2077\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>matrix<\/code><\/td>\n<td>\u5132\u5b58\u77e9\u9663\u8cc7\u6599\u7684\u4e8c\u7dad\u9663\u5217<\/td>\n<\/tr>\n<tr>\n<td><code>columns<\/code> \/ <code>rows<\/code><\/td>\n<td>\u77e9\u9663\u7684\u6b04\u6578\u8207\u5217\u6578\uff08\u4e0d\u53ef\u8b8a\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>DoubleMatrix(double[][] _input)<\/code><\/td>\n<td>\u5efa\u69cb\u5b50\uff0c\u5f9e\u8f38\u5165\u7684\u4e8c\u7dad\u9663\u5217\u5efa\u7acb\u77e9\u9663\uff0c\u4e26\u9032\u884c\u6df1\u62f7\u8c9d<\/td>\n<\/tr>\n<tr>\n<td><code>get(int row, int col)<\/code><\/td>\n<td>\u53d6\u5f97\u6307\u5b9a\u4f4d\u7f6e\u7684\u5143\u7d20\u503c<\/td>\n<\/tr>\n<tr>\n<td><code>getRows()<\/code> \/ <code>getColumns()<\/code><\/td>\n<td>\u53d6\u5f97\u77e9\u9663\u7684\u5217\u6578\u8207\u6b04\u6578<\/td>\n<\/tr>\n<tr>\n<td><code>equals(Object o)<\/code><\/td>\n<td>\u6bd4\u8f03\u5169\u500b\u77e9\u9663\u662f\u5426\u76f8\u7b49\uff0c\u5141\u8a31\u5fae\u5c0f\u8aa4\u5dee<\/td>\n<\/tr>\n<tr>\n<td><code>hashCode()<\/code><\/td>\n<td>\u6839\u64da\u77e9\u9663\u5927\u5c0f\u7522\u751f\u96dc\u6e4a\u78bc\uff08\u7c21\u55ae\u4e58\u7a4d\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\ud83d\udd12 \u8868\u793a\u4e0d\u8b8a\u5f0f\uff08Representation Invariant\uff09<\/h3>\n<p>\u9019\u4e9b\u689d\u4ef6\u4fdd\u8b49\u77e9\u9663\u7684\u7d50\u69cb\u6b63\u78ba\uff1a<\/p>\n<\/li>\n<li>\n<p><code>rows &gt;= 1<\/code>\uff0c<code>columns &gt;= 1<\/code><\/p>\n<\/li>\n<li>\n<p><code>matrix.length == rows<\/code><\/p>\n<\/li>\n<li>\n<p><code>matrix[0].length == columns<\/code><\/p>\n<h3>\u2705 \u8a2d\u8a08\u512a\u9ede<\/h3>\n<\/li>\n<li>\n<p>\u4f7f\u7528 <code>Arrays.stream(...).map(...).toArray(...)<\/code> \u9032\u884c\u6df1\u62f7\u8c9d\uff0c\u907f\u514d\u5916\u90e8\u4fee\u6539\u539f\u59cb\u9663\u5217\u3002<\/p>\n<\/li>\n<li>\n<p>\u660e\u78ba\u7684\u932f\u8aa4\u8655\u7406\uff08\u4f8b\u5982 null \u6216\u7a7a\u9663\u5217\u6aa2\u67e5\uff09\u3002<\/p>\n<\/li>\n<li>\n<p>\u652f\u63f4\u77e9\u9663\u76f8\u7b49\u6bd4\u8f03\uff0c\u8003\u616e\u6d6e\u9ede\u8aa4\u5dee\u3002<\/p>\n<p>\u5982\u679c\u4f60\u60f3\u9032\u4e00\u6b65\u64f4\u5145\u9019\u500b\u985e\u5225\uff0c\u4f8b\u5982\u52a0\u5165\u77e9\u9663\u52a0\u6cd5\u3001\u8f49\u7f6e\u3001\u4e58\u6cd5\u6216\u662f\u652f\u63f4 DFT \u8f38\u51fa\u683c\u5f0f\uff0c\u6211\u53ef\u4ee5\u5e6b\u4f60\u8a2d\u8a08\u6a21\u7d44\u5316\u7684\u4ecb\u9762\u8207\u6e2c\u8a66\u6848\u4f8b\u3002\u662f\u5426\u8981\u6211\u5e6b\u4f60\u52a0\u4e0a\u4e2d\u6587\u8a3b\u89e3\u7248\u672c\u6216\u64b0\u5beb README \u6587\u4ef6\u4f86\u6559\u5b78\u4f7f\u7528\u9019\u500b\u985e\u5225\uff1f<\/p>\n<\/li>\n<\/ul>\n<\/blockquote>\n<pre><code class=\"language-java\">package ca.ubc.ece.cpen221.ip.core;\n\nimport java.util.Arrays;\n\n\/**\n* This datatype represents a matrix of &lt;code&gt;double&lt;\/code&gt; values.\n* &lt;p&gt;\n* The constant fields &lt;code&gt;width&lt;\/code&gt; and &lt;code&gt;height&lt;\/code&gt; provide\n* the dimensions of the matrix, and it is possible to compare two DoubleMatrices for\n* equality using a set &lt;code&gt;epsilon&lt;\/code&gt; value of 10^(-7).\n*\/\npublic final class DoubleMatrix {\n   public static final double epsilon = 1e-7;\n   private double[][] matrix;\n   public final int columns;\n   public final int rows;\n\n   \/*\n       Abstraction Function:\n           DoubleMatrix represents a matrix of double-precision values.\n           The matrix has dimensions height * width.\n\n       Representation Invariant:\n           rows &gt;= 1\n           columns &gt;= 1\n           matrix.length == rows\n           matrix[0].length == columns\n    *\/\n\n   \/**\n    * Create an instance of DoubleMatrix from a two-dimensional array.\n    *\n    * @param _input is not null, and _input has at least one row and at least one column.\n    *\/\n   public DoubleMatrix(double[][] _input) {\n       if (_input == null) {\n           throw new IllegalArgumentException(&quot;input cannot be null&quot;);\n       }\n\n       rows = _input.length;\n       if (rows == 0) {\n           throw new IllegalArgumentException(&quot;matrix has to have at least one row&quot;);\n       }\n\n       columns = _input[0].length;\n       if (columns == 0) {\n           throw new IllegalArgumentException(&quot;matrix has to have at least one column&quot;);\n       }\n\n       matrix = Arrays.stream(_input).map(double[]::clone).toArray(double[][]::new);\n   }\n\n   \/**\n    * Return the entry at (row, col)\n    * @param row the row of the entry to return, 0 &lt;= row &lt; rows\n    * @param col the column of the entry to return, 0 &lt;= col &lt; columns\n    * @return the entry at location (row, col)\n    *\/\n   public double get(int row, int col) {\n       return matrix[row][col];\n   }\n\n   \/**\n    * Obtain the number of rows in the matrix\n    * @return the number of rows in the matrix\n    *\/\n   public int getRows() {\n       return rows;\n   }\n\n   \/**\n    * Obtain the number of columns in the matrix\n    * @return the number of columns in the matrix\n    *\/\n   public int getColumns() {\n       return columns;\n   }\n\n   @Override\n   public boolean equals(Object o) {\n       if (!(o instanceof DoubleMatrix)) {\n           return false;\n       }\n       DoubleMatrix other = (DoubleMatrix) o;\n       if (columns != other.columns || rows != other.rows) {\n           return false;\n       }\n       for (int i = 0; i &lt; rows; i++) {\n           for (int j = 0; j &lt; columns; j++) {\n               if (Math.abs(matrix[i][j] - other.matrix[i][j]) &gt; epsilon) {\n                   return false;\n               }\n           }\n       }\n       return true;\n   }\n\n   @Override\n   public int hashCode() {\n       return columns * rows;\n   }\n}<\/code><\/pre>\n<h2>2 Image<\/h2>\n<p>\ud83d\uddbc \u985e\u5225\u529f\u80fd\u8aaa\u660e\uff08\u4e2d\u6587\uff09<\/p>\n<p>\u9019\u500b\u985e\u5225\u63d0\u4f9b\u64cd\u4f5c\u5f71\u50cf\u4e2d\u300c\u55ae\u4e00\u50cf\u7d20\u300d\u7684\u65b9\u6cd5\uff0c\u4f7f\u7528 RGB \u8272\u5f69\u683c\u5f0f\uff08\u4e0d\u652f\u63f4\u900f\u660e\u5ea6 alpha \u901a\u9053\uff09\u3002<\/p>\n<h3>\ud83d\udccc \u529f\u80fd\u6458\u8981\uff1a<\/h3>\n<ul>\n<li><strong>\u652f\u63f4\u7684\u5f71\u50cf\u683c\u5f0f<\/strong>\uff1a\u53ef\u8b80\u53d6 PNG\u3001GIF\u3001JPEG \u6a94\u6848\uff0c\u4e5f\u53ef\u5efa\u7acb\u6307\u5b9a\u5c3a\u5bf8\u7684\u7a7a\u767d\u5f71\u50cf\u3002<\/li>\n<li><strong>\u50cf\u7d20\u5ea7\u6a19\u7cfb\u7d71<\/strong>\uff1a\n<ul>\n<li>\u9810\u8a2d\u539f\u9ede\u70ba\u5de6\u4e0a\u89d2 <code>(0, 0)<\/code>\uff0c\u7b26\u5408\u5f71\u50cf\u8655\u7406\u5e38\u898b\u6163\u4f8b\u3002<\/li>\n<li>\u53ef\u900f\u904e <code>setOriginLowerLeft()<\/code> \u65b9\u6cd5\u5c07\u539f\u9ede\u6539\u70ba\u5de6\u4e0b\u89d2\u3002<\/li>\n<\/ul>\n<\/li>\n<li><strong>\u50cf\u7d20\u64cd\u4f5c\u65b9\u5f0f<\/strong>\uff1a\n<ul>\n<li>\u4f7f\u7528 <code>get()<\/code> \/ <code>set()<\/code> \u65b9\u6cd5\u642d\u914d <code>Color<\/code> \u7269\u4ef6\u4f86\u8b80\u53d6\u6216\u8a2d\u5b9a\u50cf\u7d20\u984f\u8272\u3002<\/li>\n<li>\u4f7f\u7528 <code>getRGB()<\/code> \/ <code>setRGB()<\/code> \u65b9\u6cd5\u4ee5 32 \u4f4d\u5143 <code>int<\/code> \u7de8\u78bc RGB \u8272\u5f69\uff0c\u907f\u514d\u5efa\u7acb\u66ab\u6642\u7684 <code>Color<\/code> \u7269\u4ef6\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>\ud83c\udfa8 RGB \u7de8\u78bc\u8207\u89e3\u78bc\uff1a<\/h3>\n<ul>\n<li>\n<p><strong>\u89e3\u78bc RGB\uff1a<\/strong><\/p>\n<p>java<\/p>\n<pre><code>int r = (rgb >> 16) & 0xFF;\nint g = (rgb >> 8) & 0xFF;\nint b = (rgb >> 0) & 0xFF;<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u7de8\u78bc RGB\uff1a<\/strong><\/p>\n<p>java<\/p>\n<pre><code>int rgb = (r << 16) + (g << 8) + (b << 0);<\/code><\/pre>\n<\/li>\n<\/ul>\n<h3>\ud83e\udde0 \u8a18\u61b6\u9ad4\u4f7f\u7528\u91cf\uff1a<\/h3>\n<ul>\n<li>\u4e00\u5f35 W \u00d7 H \u7684\u5f71\u50cf\u7d04\u4f7f\u7528 <code>4 \u00d7 W \u00d7 H<\/code> \u4f4d\u5143\u7d44\uff08\u6bcf\u500b\u50cf\u7d20\u4f54 32 \u4f4d\u5143\uff0c\u5373 4 bytes\uff09\u3002<\/li>\n<\/ul>\n<p>\u9019\u985e\u8a2d\u8a08\u975e\u5e38\u9069\u5408\u7528\u65bc\u5f71\u50cf\u8655\u7406\u6559\u5b78\u3001\u50cf\u7d20\u7d1a\u64cd\u4f5c\u3001\u6216\u662f\u81ea\u8a02\u6ffe\u93e1\u958b\u767c\u3002\u5982\u679c\u4f60\u9700\u8981\u5e6b\u5fd9\u64b0\u5beb\u9019\u500b\u985e\u5225\u7684\u4e2d\u6587\u8a3b\u89e3\u7248\u672c\u3001\u6e2c\u8a66\u6848\u4f8b\u3001\u6216\u662f\u6574\u5408\u9032\u4f60\u7684\u6a21\u7d44\u5316\u7cfb\u7d71\uff0c\u6211\u53ef\u4ee5\u5e6b\u4f60\u88dc\u9f4a\u3002\u662f\u5426\u8981\u6211\u5e6b\u4f60\u6574\u7406\u6210 showcase-ready \u7684\u6559\u5b78\u6a21\u7d44\uff1f<\/p>\n<pre><code class=\"language-java\">package ca.ubc.ece.cpen221.ip.core;\n\/******************************************************************************\n*  Data type for manipulating individual pixels of an image. The original\n*  image can be read from a file in JPG, GIF, or PNG format, or the\n*  user can create a blank image of a given dimension. Includes methods for\n*  displaying the image in a window on the screen or saving to a file.\n*\n*  Remarks\n*  -------\n*   - pixel (x, y) is column x and row y, where (0, 0) is upper left\n*\n******************************************************************************\/\n\nimport javax.imageio.ImageIO;\nimport javax.swing.ImageIcon;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JMenu;\nimport javax.swing.JMenuBar;\nimport javax.swing.JMenuItem;\nimport javax.swing.JPanel;\nimport javax.swing.KeyStroke;\nimport java.awt.Color;\nimport java.awt.FileDialog;\nimport java.awt.Toolkit;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.awt.event.KeyEvent;\nimport java.awt.image.BufferedImage;\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URL;\n\n\/**\n* This class provides methods for manipulating individual pixels of\n* an image using the RGB color format. The alpha component (for transparency)\n* is not currently supported.\n* The original image can be read from a {@code PNG}, {@code GIF},\n* or {@code JPEG} file or the user can create a blank image of a given dimension.\n* This class includes methods for displaying the image in a window on\n* the screen or saving it to a file.\n* &lt;p&gt;\n* Pixel (&lt;em&gt;col&lt;\/em&gt;, &lt;em&gt;row&lt;\/em&gt;) is column &lt;em&gt;col&lt;\/em&gt; and row &lt;em&gt;row&lt;\/em&gt;.\n* By default, the origin (0, 0) is the pixel in the top-left corner,\n* which is a common convention in image processing.\n* The method {@link #setOriginLowerLeft()} changes the origin to the lower left.\n* &lt;p&gt;\n* The {@code get()} and {@code set()} methods use {@link Color} objects to get\n* or set the color of the specified pixel.\n* The {@code getRGB()} and {@code setRGB()} methods use a 32-bit {@code int}\n* to encode the color, thereby avoiding the need to create temporary\n* {@code Color} objects. The red (R), green (G), and blue (B) components\n* are encoded using the least significant 24 bits.\n* Given a 32-bit {@code int} encoding the color, the following code extracts\n* the RGB components:\n* &lt;blockquote&gt;&lt;pre&gt;\n*  int r = (rgb &gt;&gt; 16) &amp; 0xFF;\n*  int g = (rgb &gt;&gt;  8) &amp; 0xFF;\n*  int b = (rgb &gt;&gt;  0) &amp; 0xFF;\n*  &lt;\/pre&gt;&lt;\/blockquote&gt;\n* Given the RGB components (8-bits each) of a color,\n* the following statement packs it into a 32-bit {@code int}:\n* &lt;blockquote&gt;&lt;pre&gt;\n*  int rgb = (r &lt;&lt; 16) + (g &lt;&lt; 8) + (b &lt;&lt; 0);\n* &lt;\/pre&gt;&lt;\/blockquote&gt;\n* &lt;p&gt;\n* A &lt;em&gt;W&lt;\/em&gt;-by-&lt;em&gt;H&lt;\/em&gt; image uses ~ 4 &lt;em&gt;W H&lt;\/em&gt; bytes of memory,\n* since the color of each pixel is encoded as a 32-bit &lt;code&gt;int&lt;\/code&gt;.\n* &lt;p&gt;\n*\/\n\npublic final class Image implements ActionListener {\n   private final int width, height;           \/\/ width and height\n   private BufferedImage image;               \/\/ the rasterized image\n   private JFrame frame;                      \/\/ on-screen view\n   private String filename;                   \/\/ name of file\n   private boolean isOriginUpperLeft = true;  \/\/ location of origin\n\n   \/**\n    * Creates a {@code width}-by-{@code height} image, with {@code width} columns\n    * and {@code height} rows, where each pixel is black.\n    *\n    * @param width  the width of the image\n    * @param height the height of the image\n    * @throws IllegalArgumentException if {@code width} is negative or zero\n    * @throws IllegalArgumentException if {@code height} is negative or zero\n    *\/\n   public Image(int width, int height) {\n       if (width &lt;= 0) {\n           throw new IllegalArgumentException(&quot;width must be positive&quot;);\n       }\n       if (height &lt;= 0) {\n           throw new IllegalArgumentException(&quot;height must be positive&quot;);\n       }\n       this.width = width;\n       this.height = height;\n       image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\n       \/\/ set to TYPE_INT_ARGB here and in next constructor to support transparency\n   }\n\n   \/**\n    * Creates a new image that is a deep copy of the argument image.\n    *\n    * @param image the image to copy\n    * @throws IllegalArgumentException if {@code image} is {@code null}\n    *\/\n   public Image(Image image) {\n       if (image == null) {\n           throw new IllegalArgumentException(&quot;constructor argument is null&quot;);\n       }\n\n       width = image.width();\n       height = image.height();\n       this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\n       filename = image.filename;\n       isOriginUpperLeft = image.isOriginUpperLeft;\n       for (int col = 0; col &lt; width(); col++) {\n           for (int row = 0; row &lt; height(); row++) {\n               this.image.setRGB(col, row, image.image.getRGB(col, row));\n           }\n       }\n   }\n\n   \/**\n    * Creates a image by reading an image from a file or URL.\n    *\n    * @param name the name of the file (.png, .gif, or .jpg) or URL.\n    * @throws IllegalArgumentException if cannot read image\n    * @throws IllegalArgumentException if {@code name} is {@code null}\n    *\/\n   public Image(String name) {\n       if (name == null) {\n           throw new IllegalArgumentException(&quot;constructor argument is null&quot;);\n       }\n\n       this.filename = name;\n       try {\n           \/\/ try to read from file in working directory\n           File file = new File(name);\n           if (file.isFile()) {\n               image = ImageIO.read(file);\n           } else {\n\n               \/\/ resource relative to .class file\n               URL url = getClass().getResource(filename);\n\n               \/\/ resource relative to classloader root\n               if (url == null) {\n                   url = getClass().getClassLoader().getResource(name);\n               }\n\n               \/\/ or URL from web\n               if (url == null) {\n                   url = new URL(name);\n               }\n\n               image = ImageIO.read(url);\n           }\n\n           if (image == null) {\n               throw new IllegalArgumentException(&quot;could not read image: &quot; + name);\n           }\n\n           width = image.getWidth(null);\n           height = image.getHeight(null);\n       }\n       catch (IOException ioe) {\n           throw new IllegalArgumentException(&quot;could not open image: &quot; + name, ioe);\n       }\n   }\n\n   \/**\n    * Creates a image by reading the image from a PNG, GIF, or JPEG file.\n    *\n    * @param file the file\n    * @throws IllegalArgumentException if cannot read image\n    * @throws IllegalArgumentException if {@code file} is {@code null}\n    *\/\n   public Image(File file) {\n       if (file == null) {\n           throw new IllegalArgumentException(&quot;constructor argument is null&quot;);\n       }\n\n       try {\n           image = ImageIO.read(file);\n       }\n       catch (IOException ioe) {\n           throw new IllegalArgumentException(&quot;could not open file: &quot; + file, ioe);\n       }\n       if (image == null) {\n           throw new IllegalArgumentException(&quot;could not read file: &quot; + file);\n       }\n       width = image.getWidth(null);\n       height = image.getHeight(null);\n       filename = file.getName();\n   }\n\n   \/**\n    * Returns the monochrome luminance of the given color as an intensity\n    * between 0.0 and 255.0 using the NTSC formula\n    * Y = 0.299*r + 0.587*g + 0.114*b. If the given color is a shade of gray\n    * (r = g = b), this method is guaranteed to return the exact grayscale\n    * value (an integer with no floating-point roundoff error).\n    *\n    * @param color the color to convert\n    * @return the monochrome luminance (between 0.0 and 255.0)\n    *\/\n   public static double intensity(Color color) {\n       int r = color.getRed();\n       int g = color.getGreen();\n       int b = color.getBlue();\n       if (r == g &amp;&amp; r == b) {\n           return r;   \/\/ to avoid floating-point issues\n       }\n       return 0.299 * r + 0.587 * g + 0.114 * b;\n   }\n\n   \/**\n    * Returns a grayscale version of the given color as a {@code Color} object.\n    *\n    * @param color the {@code Color} object to convert to grayscale\n    * @return a grayscale version of {@code color}\n    *\/\n   public static Color toGray(Color color) {\n       int y = (int) (Math.round(intensity(color)));   \/\/ round to nearest int\n       Color gray = new Color(y, y, y);\n       return gray;\n   }\n\n   \/**\n    * Are the two given colors compatible? Two colors are compatible if the\n    * the difference in their monochrome luminances is at least 128.0).\n    *\n    * @param a one color\n    * @param b the other color\n    * @return {@code true} if colors {@code a} and {@code b} are compatible;\n    * {@code false} otherwise\n    *\/\n   public static boolean areCompatible(Color a, Color b) {\n       return Math.abs(intensity(a) - intensity(b)) &gt;= 128.0;\n   }\n\n   \/**\n    * Unit tests this {@code Image} data type.\n    * Reads a image specified by the command-line argument,\n    * and shows it in a window on the screen.\n    *\n    * @param args the command-line arguments\n    *\/\n   public static void main(String[] args) {\n       Image image = new Image(args[0]);\n       System.out.printf(&quot;%d-by-%d\\n&quot;, image.width(), image.height());\n       image.show();\n   }\n\n   \/**\n    * Returns a {@link JLabel} containing this image, for embedding in a {@link JPanel},\n    * {@link JFrame} or other GUI widget.\n    *\n    * @return the {@code JLabel}\n    *\/\n   public JLabel getJLabel() {\n       if (image == null) {\n           return null;         \/\/ no image available\n       }\n       ImageIcon icon = new ImageIcon(image);\n       return new JLabel(icon);\n   }\n\n   \/**\n    * Sets the origin to be the upper left pixel. This is the default.\n    *\/\n   public void setOriginUpperLeft() {\n       isOriginUpperLeft = true;\n   }\n\n   \/**\n    * Sets the origin to be the lower left pixel.\n    *\/\n   public void setOriginLowerLeft() {\n       isOriginUpperLeft = false;\n   }\n\n   \/**\n    * Displays the image in a window on the screen.\n    *\/\n\n   \/\/ getMenuShortcutKeyMask() deprecated in Java 10 but its replacement\n   \/\/ getMenuShortcutKeyMaskEx() is not available in Java 8\n   @SuppressWarnings(&quot;deprecation&quot;)\n   public void show() {\n\n       \/\/ create the GUI for viewing the image if needed\n       if (frame == null) {\n           frame = new JFrame();\n\n           JMenuBar menuBar = new JMenuBar();\n           JMenu menu = new JMenu(&quot;File&quot;);\n           menuBar.add(menu);\n           JMenuItem menuItem1 = new JMenuItem(&quot; Save...   &quot;);\n           menuItem1.addActionListener(this);\n           menuItem1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,\n               Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));\n           menu.add(menuItem1);\n           frame.setJMenuBar(menuBar);\n           frame.setContentPane(getJLabel());\n           \/\/ f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\n           frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);\n           if (filename == null) {\n               frame.setTitle(width + &quot;-by-&quot; + height);\n           } else {\n               frame.setTitle(filename);\n           }\n           frame.setResizable(false);\n           frame.pack();\n           frame.setVisible(true);\n       }\n\n       \/\/ draw\n       frame.repaint();\n   }\n\n   \/**\n    * Returns the height of the image.\n    *\n    * @return the height of the image (in pixels)\n    *\/\n   public int height() {\n       return height;\n   }\n\n   \/**\n    * Returns the width of the image.\n    *\n    * @return the width of the image (in pixels)\n    *\/\n   public int width() {\n       return width;\n   }\n\n   private void validateRowIndex(int row) {\n       if (row &lt; 0 || row &gt;= height()) {\n           throw new IllegalArgumentException(\n               &quot;row index must be between 0 and &quot; + (height() - 1) + &quot;: &quot; + row);\n       }\n   }\n\n   private void validateColumnIndex(int col) {\n       if (col &lt; 0 || col &gt;= width()) {\n           throw new IllegalArgumentException(\n               &quot;column index must be between 0 and &quot; + (width() - 1) + &quot;: &quot; + col);\n       }\n   }\n\n   \/**\n    * Returns the color of pixel ({@code col}, {@code row}) as a {@link java.awt.Color}.\n    *\n    * @param col the column index\n    * @param row the row index\n    * @return the color of pixel ({@code col}, {@code row})\n    * @throws IllegalArgumentException unless both {@code 0 &lt;= col &lt; width} and {@code 0 &lt;= row &lt; height}\n    *\/\n   public Color get(int col, int row) {\n       validateColumnIndex(col);\n       validateRowIndex(row);\n       int rgb = getRGB(col, row);\n       return new Color(rgb);\n   }\n\n   \/**\n    * Returns the color of pixel ({@code col}, {@code row}) as an {@code int}.\n    * Using this method can be more efficient than {@link #get(int, int)} because\n    * it does not create a {@code Color} object.\n    *\n    * @param col the column index\n    * @param row the row index\n    * @return the integer representation of the color of pixel ({@code col}, {@code row})\n    * @throws IllegalArgumentException unless both {@code 0 &lt;= col &lt; width} and {@code 0 &lt;= row &lt; height}\n    *\/\n   public int getRGB(int col, int row) {\n       validateColumnIndex(col);\n       validateRowIndex(row);\n       if (isOriginUpperLeft) {\n           return image.getRGB(col, row);\n       } else {\n           return image.getRGB(col, height - row - 1);\n       }\n   }\n\n   \/**\n    * Sets the color of pixel ({@code col}, {@code row}) to given color.\n    *\n    * @param col   the column index\n    * @param row   the row index\n    * @param color the color\n    * @throws IllegalArgumentException unless both {@code 0 &lt;= col &lt; width} and {@code 0 &lt;= row &lt; height}\n    * @throws IllegalArgumentException if {@code color} is {@code null}\n    *\/\n   public void set(int col, int row, Color color) {\n       validateColumnIndex(col);\n       validateRowIndex(row);\n       if (color == null) {\n           throw new IllegalArgumentException(&quot;color argument is null&quot;);\n       }\n       int rgb = color.getRGB();\n       setRGB(col, row, rgb);\n   }\n\n   \/**\n    * Sets the color of pixel ({@code col}, {@code row}) to given color.\n    *\n    * @param col the column index\n    * @param row the row index\n    * @param rgb the integer representation of the color\n    * @throws IllegalArgumentException unless both {@code 0 &lt;= col &lt; width} and {@code 0 &lt;= row &lt; height}\n    *\/\n   public void setRGB(int col, int row, int rgb) {\n       validateColumnIndex(col);\n       validateRowIndex(row);\n       if (isOriginUpperLeft) {\n           image.setRGB(col, row, rgb);\n       } else {\n           image.setRGB(col, height - row - 1, rgb);\n       }\n   }\n\n   \/**\n    * Returns true if this image is equal to the argument image.\n    *\n    * @param other the other image\n    * @return {@code true} if this image is the same dimension as {@code other}\n    * and if all pixels have the same color; {@code false} otherwise\n    *\/\n   public boolean equals(Object other) {\n       if (other == this) {\n           return true;\n       }\n       if (other == null) {\n           return false;\n       }\n       if (other.getClass() != this.getClass()) {\n           return false;\n       }\n       Image that = (Image) other;\n       if (this.width() != that.width()) {\n           return false;\n       }\n       if (this.height() != that.height()) {\n           return false;\n       }\n       for (int col = 0; col &lt; width(); col++) {\n           for (int row = 0; row &lt; height(); row++) {\n               if (this.getRGB(col, row) != that.getRGB(col, row)) {\n                   return false;\n               }\n           }\n       }\n       return true;\n   }\n\n   \/**\n    * Returns a string representation of this image.\n    * The result is a &lt;code&gt;width&lt;\/code&gt;-by-&lt;code&gt;height&lt;\/code&gt; matrix of pixels,\n    * where the color of a pixel is represented using 6 hex digits to encode\n    * the red, green, and blue components.\n    *\n    * @return a string representation of this image\n    *\/\n   public String toString() {\n       StringBuilder sb = new StringBuilder();\n       sb.append(width + &quot;-by-&quot; + height + &quot; image (RGB values given in hex)\\n&quot;);\n       for (int row = 0; row &lt; height; row++) {\n           for (int col = 0; col &lt; width; col++) {\n               int rgb = 0;\n               if (isOriginUpperLeft) {\n                   rgb = image.getRGB(col, row);\n               } else {\n                   rgb = image.getRGB(col, height - row - 1);\n               }\n               sb.append(String.format(&quot;#%06X &quot;, rgb &amp; 0xFFFFFF));\n           }\n           sb.append(&quot;\\n&quot;);\n       }\n       return sb.toString().trim();\n   }\n\n   \/**\n    * This operation is not supported because pictures are mutable.\n    *\n    * @return does not return a value\n    * @throws UnsupportedOperationException if called\n    *\/\n   public int hashCode() {\n       throw new UnsupportedOperationException(\n           &quot;hashCode() is not supported because pictures are mutable&quot;);\n   }\n\n   \/**\n    * Saves the image to a file in either PNG or JPEG format.\n    * The filetype extension must be either .png or .jpg.\n    *\n    * @param name the name of the file\n    * @throws IllegalArgumentException if {@code name} is {@code null}\n    *\/\n   public void save(String name) {\n       if (name == null) {\n           throw new IllegalArgumentException(&quot;argument to save() is null&quot;);\n       }\n       save(new File(name));\n       filename = name;\n   }\n\n   \/**\n    * Saves the image to a file in a PNG or JPEG image format.\n    *\n    * @param file the file\n    * @throws IllegalArgumentException if {@code file} is {@code null}\n    *\/\n   public void save(File file) {\n       if (file == null) {\n           throw new IllegalArgumentException(&quot;argument to save() is null&quot;);\n       }\n       filename = file.getName();\n       if (frame != null) {\n           frame.setTitle(filename);\n       }\n       String suffix = filename.substring(filename.lastIndexOf(&#039;.&#039;) + 1);\n       if (&quot;jpg&quot;.equalsIgnoreCase(suffix) || &quot;png&quot;.equalsIgnoreCase(suffix)) {\n           try {\n               ImageIO.write(image, suffix, file);\n           }\n           catch (IOException e) {\n               e.printStackTrace();\n           }\n       } else {\n           System.out.println(&quot;Error: filename must end in .jpg or .png&quot;);\n       }\n   }\n\n   \/**\n    * Opens a save dialog box when the user selects &quot;Save As&quot; from the menu.\n    *\/\n   @Override\n   public void actionPerformed(ActionEvent e) {\n       FileDialog chooser = new FileDialog(frame,\n           &quot;Use a .png or .jpg extension&quot;, FileDialog.SAVE);\n       chooser.setVisible(true);\n       if (chooser.getFile() != null) {\n           save(chooser.getDirectory() + File.separator + chooser.getFile());\n       }\n   }\n\n}<\/code><\/pre>\n<h2>3 Rectangle<\/h2>\n<p>\u9019\u6bb5 Java \u7a0b\u5f0f\u78bc\u5b9a\u7fa9\u4e86\u4e00\u500b\u4e0d\u53ef\u8b8a\u7684 <code>Rectangle<\/code> \u985e\u5225\uff0c\u7528\u4f86\u8868\u793a\u4f4d\u65bc\u4e8c\u7dad\u5e73\u9762\u6b63\u8c61\u9650\u4e2d\u7684\u77e9\u5f62\u3002\u4ee5\u4e0b\u662f\u8a73\u7d30\u7684\u4e2d\u6587\u89e3\u91cb\u8207\u8a2d\u8a08\u5206\u6790\uff1a<\/p>\n<h3>\ud83e\uddf1 \u985e\u5225\u540d\u7a31\uff1a<code>Rectangle<\/code>\uff08\u77e9\u5f62\uff09<\/h3>\n<p>\u9019\u500b\u985e\u5225\u7684\u8a2d\u8a08\u76ee\u7684\u662f\u7528\u4f86\u8868\u793a\u5f71\u50cf\u8655\u7406\u4e2d\u5e38\u898b\u7684\u77e9\u5f62\u5340\u57df\uff0c\u4f8b\u5982 ROI\uff08Region of Interest\uff09\u6216\u88c1\u526a\u7bc4\u570d\u3002\u5b83\u662f <strong>\u4e0d\u53ef\u8b8a\u7684<\/strong>\uff0c\u4e5f\u5c31\u662f\u4e00\u65e6\u5efa\u7acb\u5f8c\uff0c\u5ea7\u6a19\u503c\u7121\u6cd5\u4fee\u6539\u3002<\/p>\n<h3>\ud83d\udcd0 \u6210\u54e1\u8b8a\u6578\u8aaa\u660e<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u6b04\u4f4d\u540d\u7a31<\/th>\n<th>\u4e2d\u6587\u8aaa\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>xTopLeft<\/code><\/td>\n<td>\u5de6\u4e0a\u89d2\u7684 x \u5ea7\u6a19\uff08\u5fc5\u9808 \u2265 0\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>yTopLeft<\/code><\/td>\n<td>\u5de6\u4e0a\u89d2\u7684 y \u5ea7\u6a19\uff08\u5fc5\u9808 \u2265 0\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>xBottomRight<\/code><\/td>\n<td>\u53f3\u4e0b\u89d2\u7684 x \u5ea7\u6a19\uff08\u5fc5\u9808 &gt; xTopLeft\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>yBottomRight<\/code><\/td>\n<td>\u53f3\u4e0b\u89d2\u7684 y \u5ea7\u6a19\uff08\u5fc5\u9808 &gt; yTopLeft\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\ud83d\udd12 \u8868\u793a\u4e0d\u8b8a\u5f0f\uff08Representation Invariant\uff09<\/h3>\n<p>\u9019\u4e9b\u689d\u4ef6\u4fdd\u8b49\u77e9\u5f62\u7684\u5e7e\u4f55\u5408\u6cd5\u6027\uff1a<\/p>\n<ul>\n<li><code>0 &lt;= xTopLeft &lt; xBottomRight<\/code><\/li>\n<li><code>0 &lt;= yTopLeft &lt; yBottomRight<\/code><\/li>\n<\/ul>\n<p>\u9019\u8868\u793a\u77e9\u5f62\u5fc5\u9808\u6709\u6b63\u9762\u7a4d\uff0c\u4e14\u4f4d\u65bc\u7b2c\u4e00\u8c61\u9650\u3002<\/p>\n<h3>\ud83e\uddf0 \u5efa\u69cb\u5b50\u908f\u8f2f<\/h3>\n<p>java<\/p>\n<pre><code>public Rectangle(int _xTopLeft, int _yTopLeft, int _xBottomRight, int _yBottomRight)<\/code><\/pre>\n<ul>\n<li>\u6aa2\u67e5\u8f38\u5165\u5ea7\u6a19\u662f\u5426\u5408\u6cd5\u3002<\/li>\n<li>\u82e5\u4e0d\u5408\u6cd5\uff08\u4f8b\u5982\u8ca0\u503c\u6216\u53f3\u4e0b\u89d2\u4e0d\u5728\u5de6\u4e0a\u89d2\u53f3\u4e0b\u65b9\uff09\uff0c\u5247\u4e1f\u51fa <code>IllegalArgumentException<\/code>\u3002<\/li>\n<li>\u82e5\u5408\u6cd5\uff0c\u5247\u521d\u59cb\u5316\u56db\u500b\u5ea7\u6a19\u6b04\u4f4d\u3002<\/li>\n<\/ul>\n<h3>\u2705 \u8a2d\u8a08\u512a\u9ede<\/h3>\n<ul>\n<li><strong>\u4e0d\u53ef\u8b8a\u6027<\/strong>\uff1a\u4f7f\u7528 <code>final<\/code> \u6b04\u4f4d\uff0c\u78ba\u4fdd\u7269\u4ef6\u5efa\u7acb\u5f8c\u4e0d\u6703\u88ab\u4fee\u6539\uff0c\u63d0\u5347\u5b89\u5168\u6027\u8207\u53ef\u9810\u6e2c\u6027\u3002<\/li>\n<li><strong>\u6e05\u695a\u7684\u62bd\u8c61\u51fd\u6578\u8207\u4e0d\u8b8a\u5f0f<\/strong>\uff1a\u6709\u52a9\u65bc\u6559\u5b78\u8207\u7dad\u8b77\u3002<\/li>\n<li><strong>\u932f\u8aa4\u9632\u7bc4<\/strong>\uff1a\u5efa\u69cb\u5b50\u4e2d\u52a0\u5165\u8f38\u5165\u9a57\u8b49\uff0c\u907f\u514d\u5efa\u7acb\u975e\u6cd5\u77e9\u5f62\u3002<\/li>\n<\/ul>\n<p>\u5982\u679c\u4f60\u6253\u7b97\u5c07\u9019\u500b\u985e\u5225\u7528\u65bc\u5f71\u50cf\u8655\u7406\u6a21\u7d44\uff08\u4f8b\u5982\u88c1\u526a\u3001\u6a19\u8a18\u3001\u6216\u5340\u57df\u5206\u6790\uff09\uff0c\u6211\u53ef\u4ee5\u5e6b\u4f60\u64f4\u5145\u529f\u80fd\uff0c\u4f8b\u5982\uff1a<\/p>\n<ul>\n<li>\u8a08\u7b97\u9762\u7a4d<\/li>\n<li>\u5224\u65b7\u662f\u5426\u91cd\u758a<\/li>\n<li>\u8f49\u63db\u70ba <code>Image<\/code> \u6a21\u7d44\u4e2d\u7684\u50cf\u7d20\u7bc4\u570d<\/li>\n<li>\u52a0\u5165 <code>toString()<\/code> \u6216 <code>equals()<\/code> \u65b9\u6cd5\u4ee5\u4fbf\u6e2c\u8a66\u8207\u9664\u932f<\/li>\n<\/ul>\n<p>\u9700\u8981\u6211\u5e6b\u4f60\u52a0\u4e0a\u4e2d\u6587\u8a3b\u89e3\u7248\u672c\u6216\u64b0\u5beb\u6559\u5b78\u6587\u4ef6\u55ce\uff1f\u6211\u4e5f\u53ef\u4ee5\u5e6b\u4f60\u8a2d\u8a08\u6e2c\u8a66\u6848\u4f8b\u4f86\u9a57\u8b49\u77e9\u5f62\u5408\u6cd5\u6027\u8207\u908a\u754c\u884c\u70ba\u3002<\/p>\n<pre><code class=\"language-java\">package ca.ubc.ece.cpen221.ip.core;\n\n\/**\n* This datatype represents an &lt;strong&gt;immutable&lt;\/strong&gt; Rectangle\n* in the positive quadrant of the 2D plane. These rectangles match\n* standard image representations with the coordinate values for the\n* top-left corner being smaller than the coordinate values for the\n* bottom-right corner.\n*\n* After an instance is created, the coordinates of the top-left and bottom-right\n* corners can be accessed using the constant fields\n* &lt;code&gt;xTopLeft, yTopLeft, xBottomRight, yBottomRight&lt;\/code&gt;.\n*\/\npublic class Rectangle {\n\n   public final int xTopLeft, yTopLeft;\n   public final int xBottomRight, yBottomRight;\n\n   \/*\n       Abstraction Function: Represents a rectangle using its top-left corner and bottom-right\n       corner. xTopLeft is the x-coordinate of the top-left corner and yTopLeft is the y-coordinate\n       of the top-left corner. xBottomRight and yBottom right are the x- and y- coordinates\n       of the bottom-right corner.\n\n       Representation Invariant:\n           0 &lt;= xTopLeft &lt; xBottomRight\n           0 &lt;= yTopLeft &lt; yBottomRight\n   *\/\n\n   \/**\n    * Create a new Rectangle.\n    *\n    * @param _xTopLeft: is the x coordinate of the top-left corner and should be &gt;= 0\n    * @param _yTopLeft: is the y coordinate of the top-left corner and should be &gt;= 0\n    * @param _xBottomRight: is the x coordinate of the bottom-right corner and should be &gt; _xTopLeft\n    * @param _yBottomRight: is the y coordinate of the bottom-right corner and should be &gt; _yTopLeft\n    *\/\n   public Rectangle(int _xTopLeft, int _yTopLeft, int _xBottomRight, int _yBottomRight) {\n       if (_xTopLeft &lt; 0 || _yTopLeft &lt; 0 ||\n           _xBottomRight &lt;= _xTopLeft || _yBottomRight &lt;= _yTopLeft) {\n           throw new IllegalArgumentException(&quot;Invalid rectangle specified.&quot;);\n       }\n\n       xTopLeft = _xTopLeft;\n       yTopLeft = _yTopLeft;\n       xBottomRight = _xBottomRight;\n       yBottomRight = _yBottomRight;\n   }\n\n}<\/code><\/pre>\n<h2>4 DFTOutput<\/h2>\n<p>\u9019\u6bb5 Java \u7a0b\u5f0f\u78bc\u5b9a\u7fa9\u4e86\u4e00\u500b <code>DFTOutput<\/code> \u985e\u5225\uff0c\u7528\u4f86\u8868\u793a\u7a7a\u9593\u96e2\u6563\u5085\u7acb\u8449\u8f49\u63db\uff08DFT\uff09\u7684\u8f38\u51fa\u7d50\u679c\u3002\u4ee5\u4e0b\u662f\u4e2d\u6587\u89e3\u6790\u8207\u8a2d\u8a08\u91cd\u9ede\uff1a<\/p>\n<h3>\ud83d\udce6 \u985e\u5225\u540d\u7a31\uff1a<code>DFTOutput<\/code>\uff08\u96e2\u6563\u5085\u7acb\u8449\u8f49\u63db\u8f38\u51fa\uff09<\/h3>\n<p>\u6b64\u985e\u5225\u5c01\u88dd\u4e86 DFT \u7684\u5169\u500b\u6838\u5fc3\u7d50\u679c\uff1a<\/p>\n<ul>\n<li><strong>\u632f\u5e45\u77e9\u9663\uff08Amplitude\uff09<\/strong><\/li>\n<li><strong>\u76f8\u4f4d\u77e9\u9663\uff08Phase\uff09<\/strong><\/li>\n<\/ul>\n<p>\u9019\u7a2e\u8868\u793a\u65b9\u5f0f\u662f\u5c07\u8907\u6578\u5f62\u5f0f\u7684 DFT \u7d50\u679c\u62c6\u89e3\u70ba\u5169\u500b <code>DoubleMatrix<\/code>\uff0c\u4fbf\u65bc\u5f8c\u7e8c\u5f71\u50cf\u8655\u7406\u8207\u8996\u89ba\u5316\u3002<\/p>\n<h3>\ud83e\udde9 \u985e\u5225\u6210\u54e1\u8207\u529f\u80fd<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u6210\u54e1\/\u65b9\u6cd5<\/th>\n<th>\u4e2d\u6587\u8aaa\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>amplitude<\/code><\/td>\n<td>\u5132\u5b58 DFT \u7684\u632f\u5e45\u90e8\u5206\uff08\u6a21\u9577\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>phase<\/code><\/td>\n<td>\u5132\u5b58 DFT \u7684\u76f8\u4f4d\u90e8\u5206\uff08\u89d2\u5ea6\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>DFTOutput(double[][] _amplitude, double[][] _phase)<\/code><\/td>\n<td>\u5efa\u69cb\u5b50\uff0c\u5f9e\u5169\u500b\u4e8c\u7dad\u9663\u5217\u5efa\u7acb\u632f\u5e45\u8207\u76f8\u4f4d\u77e9\u9663<\/td>\n<\/tr>\n<tr>\n<td><code>equals(Object o)<\/code><\/td>\n<td>\u6bd4\u8f03\u5169\u500b DFTOutput \u662f\u5426\u76f8\u7b49\uff08\u632f\u5e45\u8207\u76f8\u4f4d\u7686\u76f8\u540c\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>hashCode()<\/code><\/td>\n<td>\u4f7f\u7528\u632f\u5e45\u77e9\u9663\u7684\u96dc\u6e4a\u78bc\u4f5c\u70ba\u6574\u9ad4\u96dc\u6e4a\u503c<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\ud83d\udd12 \u8868\u793a\u4e0d\u8b8a\u5f0f\uff08Representation Invariant\uff09<\/h3>\n<ul>\n<li><code>amplitude.width == phase.width<\/code><\/li>\n<li><code>amplitude.height == phase.height<\/code><\/li>\n<\/ul>\n<p>\u9019\u4fdd\u8b49\u5169\u500b\u77e9\u9663\u5728\u7dad\u5ea6\u4e0a\u5b8c\u5168\u4e00\u81f4\uff0c\u624d\u80fd\u5c0d\u61c9\u6bcf\u500b\u50cf\u7d20\u7684\u983b\u7387\u6210\u5206\u3002<\/p>\n<h3>\ud83e\udde0 \u8a2d\u8a08\u91cd\u9ede<\/h3>\n<ul>\n<li>\u4f7f\u7528 <code>DoubleMatrix<\/code> \u985e\u5225\u4f86\u5c01\u88dd\u6578\u503c\u77e9\u9663\uff0c\u78ba\u4fdd\u8cc7\u6599\u4e0d\u53ef\u8b8a\u4e14\u5177\u5099\u6bd4\u8f03\u529f\u80fd\u3002<\/li>\n<li>\u5efa\u69cb\u5b50\u4e2d\u9032\u884c\u7dad\u5ea6\u4e00\u81f4\u6027\u6aa2\u67e5\uff0c\u907f\u514d\u932f\u8aa4\u8f38\u5165\u3002<\/li>\n<li>\u652f\u63f4 <code>.equals()<\/code> \u65b9\u6cd5\uff0c\u4fbf\u65bc\u6e2c\u8a66\u8207\u8cc7\u6599\u6bd4\u5c0d\u3002<\/li>\n<li>\u4f7f\u7528 <code>.hashCode()<\/code> \u65b9\u6cd5\u652f\u63f4\u96dc\u6e4a\u7d50\u69cb\uff08\u4f8b\u5982 HashMap\uff09\u3002<\/li>\n<\/ul>\n<h3>\u2705 \u5ef6\u4f38\u5efa\u8b70<\/h3>\n<p>\u82e5\u4f60\u6253\u7b97\u9032\u4e00\u6b65\u8655\u7406 DFT \u7d50\u679c\uff0c\u4f8b\u5982\uff1a<\/p>\n<ul>\n<li>\u53ef\u8996\u5316\u983b\u8b5c\uff08\u4f7f\u7528 log scale\uff09<\/li>\n<li>\u53cd\u8f49 DFT\uff08IDFT\uff09<\/li>\n<li>\u6ffe\u6ce2\u5668\u8a2d\u8a08\uff08\u4f4e\u901a\u3001\u9ad8\u901a\u3001\u5e36\u901a\uff09<\/li>\n<\/ul>\n<p>\u6211\u53ef\u4ee5\u5e6b\u4f60\u8a2d\u8a08\u5c0d\u61c9\u7684\u6a21\u7d44\u8207\u6e2c\u8a66\u6848\u4f8b\uff0c\u4e26\u88dc\u4e0a\u4e2d\u82f1\u6587\u8a3b\u89e3\u8207 README \u6587\u4ef6\u3002\u5982\u679c\u4f60\u5e0c\u671b\u9019\u500b\u985e\u5225\u80fd\u652f\u63f4\u8907\u6578\u5f62\u5f0f\u6216\u8207 <code>Image<\/code> \u985e\u5225\u6574\u5408\uff0c\u4e5f\u53ef\u4ee5\u4e00\u8d77\u898f\u5283\u3002\u8981\u4e0d\u8981\u6211\u5e6b\u4f60\u88dc\u4e0a <code>getAmplitude()<\/code> \/ <code>getPhase()<\/code> \u65b9\u6cd5\u4f86\u8b93\u5916\u90e8\u6a21\u7d44\u5b58\u53d6\u9019\u4e9b\u77e9\u9663\uff1f\u9019\u6a23\u6703\u66f4\u6a21\u7d44\u5316\u3002<\/p>\n<pre><code class=\"language-java\">package ca.ubc.ece.cpen221.ip.mp;\n\nimport ca.ubc.ece.cpen221.ip.core.DoubleMatrix;\n\n\/**\n* This datatype represents the output of a spatial Discrete Fourier Transform,\n* and holds the amplitude and phase matrix obtained from the DFT.\n*\/\npublic class DFTOutput {\n   private DoubleMatrix amplitude;\n   private DoubleMatrix phase;\n\n   \/*\n       Abstraction Function:\n           Represents the output of the (spatial) DFT applied to an image.\n           amplitude is a matrix that represents the amplitude portion of the DFT output.\n           phase is a matrix that represents the phase portion of the DFT output.\n\n       Note:\n           A DFT can usually be represented by a matrix of complex numbers but\n           we use the amplitude &amp; phase representation using two matrices.\n\n       Representation Invariant:\n           amplitude.width == phase.width\n           amplitude.height == phase.width\n    *\/\n\n   \/**\n    * Create a new DFTOutput instance.\n    *\n    * @param _amplitude is not null\n    * @param _phase is not null, and is equal in dimensions to _amplitude\n    *\/\n   public DFTOutput(double[][] _amplitude, double[][] _phase) {\n       amplitude = new DoubleMatrix(_amplitude);\n       phase = new DoubleMatrix(_phase);\n       if (amplitude.columns != phase.columns || amplitude.rows != phase.rows) {\n           throw new IllegalArgumentException(\n               &quot;amplitude and phase matrices should have the same dimensions&quot;\n           );\n       }\n   }\n\n   @Override\n   public boolean equals(Object o) {\n       if (!(o instanceof DFTOutput)) {\n           return false;\n       }\n       DFTOutput other = (DFTOutput) o;\n       return amplitude.equals(other.amplitude) &amp;&amp; phase.equals(other.phase);\n   }\n\n   @Override\n   public int hashCode() {\n       return amplitude.hashCode();\n   }\n}<\/code><\/pre>\n<h2>5 ImageProcessing<\/h2>\n<p>\u9019\u6bb5\u7a0b\u5f0f\u78bc\u5b9a\u7fa9\u4e86 <code>ImageProcessing<\/code> \u985e\u5225\uff0c\u76ee\u7684\u662f\u8655\u7406\u591a\u5f35\u5f71\u50cf\u4e4b\u9593\u7684\u6bd4\u8f03\u8207\u5339\u914d\u3002\u4ee5\u4e0b\u662f\u4e2d\u6587\u89e3\u6790\u8207\u5efa\u8b70\u5be6\u4f5c\u65b9\u5411\uff1a<\/p>\n<h3>\ud83d\udce6 \u985e\u5225\u540d\u7a31\uff1a<code>ImageProcessing<\/code><\/h3>\n<p>\u6b64\u985e\u5225\u63d0\u4f9b\u91dd\u5c0d\u300c\u591a\u5f35\u5f71\u50cf\u300d\u7684\u64cd\u4f5c\u65b9\u6cd5\uff0c\u5c6c\u65bc\u5f71\u50cf\u8655\u7406\u6a21\u7d44\u4e2d\u7684\u9ad8\u968e\u908f\u8f2f\u90e8\u5206\u3002<\/p>\n<h3>\ud83e\udde0 \u65b9\u6cd5\u8aaa\u660e\u8207\u4e2d\u6587\u89e3\u91cb<\/h3>\n<h4>1. <code>cosineSimilarity(Image img1, Image img2)<\/code><\/h4>\n<ul>\n<li><strong>\u529f\u80fd\u76ee\u6a19<\/strong>\uff1a\u8a08\u7b97\u5169\u5f35\u5f71\u50cf\u4e4b\u9593\u7684\u9918\u5f26\u76f8\u4f3c\u5ea6\uff08Cosine Similarity\uff09\uff0c\u7528\u4f86\u8861\u91cf\u5b83\u5011\u7684\u76f8\u4f3c\u7a0b\u5ea6\u3002<\/li>\n<li><strong>\u61c9\u7528\u5834\u666f<\/strong>\uff1a\u5f71\u50cf\u6bd4\u5c0d\u3001\u641c\u5c0b\u3001\u5206\u985e\u3002<\/li>\n<li><strong>\u5be6\u4f5c\u5efa\u8b70<\/strong>\uff1a\n<ul>\n<li>\u5c07\u5f71\u50cf\u8f49\u63db\u70ba\u5411\u91cf\uff08\u4f8b\u5982\u7070\u968e\u50cf\u7d20\u5c55\u5e73\u70ba\u4e00\u7dad\u9663\u5217\uff09\u3002<\/li>\n<li>\u4f7f\u7528\u516c\u5f0f\uff1a<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>similarity=A\u20d7\u22c5B\u20d7\u2225A\u20d7\u2225\u22c5\u2225B\u20d7\u2225\\text{similarity} = \\frac{\\vec{A} \\cdot \\vec{B}}{|\\vec{A}| \\cdot |\\vec{B}|}<\/p>\n<ul>\n<li>\u6ce8\u610f\u8655\u7406\u4e0d\u540c\u5c3a\u5bf8\u7684\u5f71\u50cf\uff08\u53ef\u80fd\u9700\u5148 resize \u6216 crop\uff09\u3002<\/li>\n<\/ul>\n<h4>2. <code>bestMatch(Image img, List&lt;Image&gt; matchingCandidates)<\/code><\/h4>\n<ul>\n<li><strong>\u529f\u80fd\u76ee\u6a19<\/strong>\uff1a\u5f9e\u5019\u9078\u5f71\u50cf\u6e05\u55ae\u4e2d\u627e\u51fa\u8207\u76ee\u6a19\u5f71\u50cf\u6700\u76f8\u4f3c\u7684\u5f71\u50cf\uff08\u6216\u591a\u5f35\uff09\u3002<\/li>\n<li><strong>\u61c9\u7528\u5834\u666f<\/strong>\uff1a\u5f71\u50cf\u641c\u5c0b\u3001\u63a8\u85a6\u7cfb\u7d71\u3002<\/li>\n<li><strong>\u5be6\u4f5c\u5efa\u8b70<\/strong>\uff1a\n<ul>\n<li>\u5c0d\u6bcf\u5f35\u5019\u9078\u5f71\u50cf\u4f7f\u7528 <code>cosineSimilarity()<\/code> \u8a08\u7b97\u76f8\u4f3c\u5ea6\u3002<\/li>\n<li>\u6839\u64da\u76f8\u4f3c\u5ea6\u6392\u5e8f\uff0c\u9078\u51fa\u6700\u4f73\u5339\u914d\uff08\u53ef\u56de\u50b3 top-N \u6216 threshold \u4ee5\u4e0a\u8005\uff09\u3002<\/li>\n<li>\u56de\u50b3 <code>List&lt;Image&gt;<\/code> \u4ee5\u652f\u63f4\u591a\u500b\u5339\u914d\u7d50\u679c\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>\u2705 \u5ef6\u4f38\u5efa\u8b70<\/h3>\n<p>\u5982\u679c\u4f60\u5e0c\u671b\u9019\u500b\u6a21\u7d44\u66f4\u5b8c\u6574\uff0c\u6211\u53ef\u4ee5\u5e6b\u4f60\u88dc\u4e0a\uff1a<\/p>\n<ul>\n<li>\u5f71\u50cf\u5411\u91cf\u5316\u5de5\u5177\uff08\u4f8b\u5982 <code>Image.toVector()<\/code>\uff09<\/li>\n<li>\u7070\u968e\u8f49\u63db\u8207\u6a19\u6e96\u5316\u65b9\u6cd5<\/li>\n<li>\u6e2c\u8a66\u6848\u4f8b\u8207\u6548\u80fd\u5206\u6790<\/li>\n<li>\u4e2d\u82f1\u6587\u8a3b\u89e3\u8207 README \u6587\u4ef6<\/li>\n<\/ul>\n<p>\u662f\u5426\u8981\u6211\u5e6b\u4f60\u64b0\u5beb <code>cosineSimilarity<\/code> \u7684\u5be6\u4f5c\u7bc4\u4f8b\uff1f\u6211\u53ef\u4ee5\u63d0\u4f9b\u6a21\u7d44\u5316\u3001\u53ef\u6e2c\u8a66\u7684\u7248\u672c\uff0c\u4e26\u9644\u4e0a\u8a3b\u89e3\u8aaa\u660e\u6bcf\u4e00\u6b65\u3002\u9019\u6a23\u6703\u66f4\u9069\u5408\u6559\u5b78\u8207\u5c55\u793a\u3002<\/p>\n<pre><code class=\"language-java\">package ca.ubc.ece.cpen221.ip.mp;\n\nimport ca.ubc.ece.cpen221.ip.core.Image;\n\nimport java.util.List;\n\n\/**\n* This class provides some simple operations involving\n* more than one image.\n*\/\npublic class ImageProcessing {\n\n   \/* ===== TASK 3 ===== *\/\n\n   public static double cosineSimilarity(Image img1, Image img2) {\n       \/\/ TODO: Implement this method\n       return -1;\n   }\n\n   public static List&lt;Image&gt; bestMatch(Image img, List&lt;Image&gt; matchingCandidates) {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n\n}<\/code><\/pre>\n<h2>6 ImageTransformer<\/h2>\n<p>\u9019\u6bb5\u7a0b\u5f0f\u78bc\u5b9a\u7fa9\u4e86\u4e00\u500b\u529f\u80fd\u8c50\u5bcc\u7684\u5f71\u50cf\u8f49\u63db\u985e\u5225 <code>ImageTransformer<\/code>\uff0c\u8a2d\u8a08\u4e0a\u975e\u5e38\u9069\u5408\u9032\u884c\u6a21\u7d44\u5316\u5f71\u50cf\u8655\u7406\u3002\u4ee5\u4e0b\u662f\u4e2d\u6587\u89e3\u6790\u8207\u5efa\u8b70\u88dc\u5145\uff1a<\/p>\n<h3>\ud83e\uddf1 \u985e\u5225\u540d\u7a31\uff1a<code>ImageTransformer<\/code>\uff08\u5f71\u50cf\u8f49\u63db\u5668\uff09<\/h3>\n<p>\u6b64\u985e\u5225\u7684\u76ee\u7684\u662f\u5c0d\u5f71\u50cf\u9032\u884c\u5404\u7a2e\u8996\u89ba\u6548\u679c\u8655\u7406\uff0c\u4e26\u4fdd\u8b49\u539f\u59cb\u5f71\u50cf\u4e0d\u88ab\u4fee\u6539\uff08\u4e0d\u53ef\u8b8a\u6027\u8a2d\u8a08\uff09\u3002<\/p>\n<h3>\ud83d\udccc \u6210\u54e1\u8b8a\u6578\u8aaa\u660e<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u6210\u54e1<\/th>\n<th>\u4e2d\u6587\u8aaa\u660e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>image<\/code><\/td>\n<td>\u539f\u59cb\u5f71\u50cf\u8cc7\u6599\uff08\u4e0d\u6703\u88ab\u4fee\u6539\uff09<\/td>\n<\/tr>\n<tr>\n<td><code>width<\/code> \/ <code>height<\/code><\/td>\n<td>\u5f71\u50cf\u7684\u5bec\u5ea6\u8207\u9ad8\u5ea6\uff0c\u7528\u65bc\u50cf\u7d20\u8ff4\u5708<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\u2705 \u5df2\u5be6\u4f5c\u65b9\u6cd5\u89e3\u6790<\/h3>\n<h4><code>grayscale()<\/code><\/h4>\n<ul>\n<li>\u5c07\u5f71\u50cf\u8f49\u63db\u70ba\u7070\u968e\u3002<\/li>\n<li>\u4f7f\u7528 <code>Image.toGray(Color)<\/code> \u5c07\u6bcf\u500b\u50cf\u7d20\u8f49\u63db\u70ba\u7070\u968e\u8272\u3002<\/li>\n<\/ul>\n<h4><code>red()<\/code><\/h4>\n<ul>\n<li>\u4fdd\u7559\u7d05\u8272\u901a\u9053\uff0c\u5c07\u7da0\u8272\u8207\u85cd\u8272\u8a2d\u70ba 0\u3002<\/li>\n<li>\u4f7f\u7528\u4f4d\u5143\u64cd\u4f5c\u63d0\u53d6 RGB \u4e26\u91cd\u7d44\u50cf\u7d20\u3002<\/li>\n<\/ul>\n<h3>\ud83e\udde0 \u5f85\u5be6\u4f5c\u65b9\u6cd5\u5efa\u8b70<\/h3>\n<h4>TASK 1\uff1a\u57fa\u672c\u8996\u89ba\u6548\u679c<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u65b9\u6cd5<\/th>\n<th>\u5efa\u8b70\u5be6\u4f5c\u908f\u8f2f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>mirror()<\/code><\/td>\n<td>\u6c34\u5e73\u7ffb\u8f49\u5f71\u50cf\uff1a\u5c07 <code>(col, row)<\/code> \u6620\u5c04\u70ba <code>(width - 1 - col, row)<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>negative()<\/code><\/td>\n<td>\u5c0d\u6bcf\u500b\u50cf\u7d20 <code>(r, g, b)<\/code> \u8a08\u7b97 <code>(255 - r, 255 - g, 255 - b)<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>posterize()<\/code><\/td>\n<td>\u5c07\u8272\u5f69\u5206\u6bb5\uff0c\u4f8b\u5982\u6bcf\u500b\u901a\u9053\u53ea\u4fdd\u7559 4 \u500b\u5c64\u7d1a\uff08\u985e\u4f3c\u6f2b\u756b\u98a8\u683c\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>TASK 2\uff1a\u9032\u968e\u8655\u7406<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u65b9\u6cd5<\/th>\n<th>\u5efa\u8b70\u5be6\u4f5c\u908f\u8f2f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>denoise()<\/code><\/td>\n<td>\u4f7f\u7528\u4e2d\u503c\u6ffe\u6ce2\u6216\u9ad8\u65af\u6ffe\u6ce2\uff0c\u79fb\u9664\u96dc\u8a0a<\/td>\n<\/tr>\n<tr>\n<td><code>weather()<\/code><\/td>\n<td>\u6a21\u64ec\u8001\u820a\u6216\u892a\u8272\u6548\u679c\uff0c\u53ef\u52a0\u5165\u96a8\u6a5f\u96dc\u8a0a\u8207\u8272\u5f69\u504f\u79fb<\/td>\n<\/tr>\n<tr>\n<td><code>blockPaint(int blockSize)<\/code><\/td>\n<td>\u5c07\u5f71\u50cf\u5206\u6210\u5340\u584a\uff0c\u6bcf\u584a\u7528\u5e73\u5747\u8272\u586b\u5145\uff08\u50cf\u7d20\u5316\u6548\u679c\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>TASK 4\uff1a\u7da0\u5e55\u5408\u6210<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u65b9\u6cd5<\/th>\n<th>\u5efa\u8b70\u5be6\u4f5c\u908f\u8f2f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>greenScreen(Color screenColour, Image backgroundImage)<\/code><\/td>\n<td>\u5c07\u6307\u5b9a\u984f\u8272\u5340\u57df\u66ff\u63db\u70ba\u80cc\u666f\u5f71\u50cf\u5c0d\u61c9\u50cf\u7d20\uff0c\u53ef\u7528\u8272\u5dee\u95be\u503c\u5224\u65b7<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>TASK 5\uff1a\u6587\u5b57\u5c0d\u9f4a<\/h4>\n<table>\n<thead>\n<tr>\n<th>\u65b9\u6cd5<\/th>\n<th>\u5efa\u8b70\u5be6\u4f5c\u908f\u8f2f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>alignTextImage()<\/code><\/td>\n<td>\u5075\u6e2c\u6587\u5b57\u5340\u57df\u4e26\u5c45\u4e2d\u6392\u5217\uff0c\u53ef\u80fd\u9700\u7d50\u5408\u908a\u7de3\u5075\u6e2c\u8207\u6295\u5f71\u5206\u6790<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\ud83d\udd27 \u5efa\u69cb\u5b50\u88dc\u5145\u5efa\u8b70<\/h3>\n<p>\u76ee\u524d <code>ImageTransformer(Image img)<\/code> \u5c1a\u672a\u5be6\u4f5c\uff0c\u5efa\u8b70\u5982\u4e0b\uff1a<\/p>\n<p>java<\/p>\n<pre><code>public ImageTransformer(Image img) {\n    if (img == null) {\n        throw new IllegalArgumentException(&quot;Image cannot be null&quot;);\n    }\n    this.image = img;\n    this.width = img.getWidth();\n    this.height = img.getHeight();\n}<\/code><\/pre>\n<h3>\ud83d\udcda \u5ef6\u4f38\u652f\u63f4<\/h3>\n<p>\u5982\u679c\u4f60\u5e0c\u671b\u9019\u500b\u6a21\u7d44\u80fd\u5c55\u793a\u65bc\u6559\u5b78\u6216\u5c55\u793a\u7cfb\u7d71\uff0c\u6211\u53ef\u4ee5\u5e6b\u4f60\uff1a<\/p>\n<ul>\n<li>\u52a0\u4e0a\u4e2d\u82f1\u6587\u8a3b\u89e3<\/li>\n<li>\u64b0\u5beb README \u6587\u4ef6<\/li>\n<li>\u88dc\u4e0a\u6e2c\u8a66\u6848\u4f8b\uff08JUnit\uff09<\/li>\n<li>\u88fd\u4f5c\u6a21\u64ec\u8173\u672c\u8207\u7bc4\u4f8b\u8f38\u51fa<\/li>\n<\/ul>\n<p>\u662f\u5426\u8981\u6211\u5e6b\u4f60\u512a\u5316 <code>mirror()<\/code> \u6216 <code>negative()<\/code> \u7684\u5be6\u4f5c\uff1f\u6211\u53ef\u4ee5\u63d0\u4f9b\u6a21\u7d44\u5316\u3001\u53ef\u6e2c\u8a66\u7684\u7248\u672c\uff0c\u4e26\u9644\u8a3b\u6559\u5b78\u8aaa\u660e\u3002\u9019\u6a23\u6703\u66f4\u9069\u5408\u5c55\u793a\u8207\u6559\u5b78\u7528\u9014\u3002<\/p>\n<pre><code class=\"language-java\">package ca.ubc.ece.cpen221.ip.mp;\n\nimport ca.ubc.ece.cpen221.ip.core.Image;\nimport ca.ubc.ece.cpen221.ip.core.ImageProcessingException;\nimport ca.ubc.ece.cpen221.ip.core.Rectangle;\n\nimport java.awt.Color;\n\n\/**\n* This datatype (or class) provides operations for transforming an image.\n*\n* &lt;p&gt;The operations supported are:\n* &lt;ul&gt;\n*     &lt;li&gt;The {@code ImageTransformer} constructor generates an instance of an image that\n*     we would like to transform;&lt;\/li&gt;\n*     &lt;li&gt;&lt;\/li&gt;\n* &lt;\/ul&gt;\n* &lt;\/p&gt;\n*\/\n\npublic class ImageTransformer {\n\n   private Image image;\n   private int width;\n   private int height;\n\n   \/**\n    * Creates an ImageTransformer with an image. The provided image is\n    * &lt;strong&gt;never&lt;\/strong&gt; changed by any of the operations.\n    *\n    * @param img is not null\n    *\/\n   public ImageTransformer(Image img) {\n       \/\/ TODO: Implement this method\n   }\n\n   \/**\n    * Obtain the grayscale version of the image.\n    *\n    * @return the grayscale version of the instance.\n    *\/\n   public Image grayscale() {\n       Image gsImage = new Image(width, height);\n       for (int col = 0; col &lt; width; col++) {\n           for (int row = 0; row &lt; height; row++) {\n               Color color = image.get(col, row);\n               Color gray = Image.toGray(color);\n               gsImage.set(col, row, gray);\n           }\n       }\n       return gsImage;\n   }\n\n   \/**\n    * Obtain a version of the image with only the red colours.\n    *\n    * @return a reds-only version of the instance.\n    *\/\n   public Image red() {\n       Image redImage = new Image(width, height);\n       for (int col = 0; col &lt; width; col++) {\n           for (int row = 0; row &lt; height; row++) {\n               int originalPixel = image.getRGB(col, row);\n               int alpha = (originalPixel &gt;&gt; 24) &amp; 0xFF;\n               int red = (originalPixel &gt;&gt; 16) &amp; 0xFF;\n               int desiredColor = (alpha &lt;&lt; 24) | (red &lt;&lt; 16) | (0 &lt;&lt; 8) | (0);\n               redImage.setRGB(col, row, desiredColor);\n           }\n       }\n       return redImage;\n   }\n\n   \/* ===== TASK 1 ===== *\/\n\n   \/**\n    * Returns the mirror image of an instance.\n    *\n    * @return the mirror image of the instance.\n    *\/\n   public Image mirror() {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n\n   \/**\n    * &lt;p&gt;Returns the negative version of an instance.&lt;br \/&gt;\n    * If the colour of a pixel is (r, g, b) then the colours of the same pixel\n    * in the negative of the image are (255-r, 255-g, 255-b).&lt;\/p&gt;\n    *\n    * @return the negative of the instance.\n    *\/\n   public Image negative() {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n\n   public Image posterize() {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n\n   \/* ===== TASK 2 ===== *\/\n\n   public Image denoise() {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n\n   \/**\n    * @return a weathered version of the image.\n    *\/\n   public Image weather() {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n\n   public Image blockPaint(int blockSize) {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n\n   \/* ===== TASK 4 ===== *\/\n\n   public Image greenScreen(Color screenColour, Image backgroundImage) {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n\n   \/* ===== TASK 5 ===== *\/\n\n   public Image alignTextImage() {\n       \/\/ TODO: Implement this method\n       return null;\n   }\n}<\/code><\/pre>\n<h2>7 Task1test<\/h2>\n<p>\u9019\u662f\u4e00\u7d44\u91dd\u5c0d <code>ImageTransformer<\/code> \u985e\u5225\u7684 JUnit \u6e2c\u8a66\u6848\u4f8b\uff0c\u5c6c\u65bc Task 1 \u7684\u9a57\u8b49\u6a21\u7d44\u3002\u4ee5\u4e0b\u662f\u4e2d\u6587\u89e3\u6790\u8207\u5efa\u8b70\u88dc\u5145\uff1a<\/p>\n<h3>\ud83e\uddea \u6e2c\u8a66\u985e\u5225\uff1a<code>Task1Tests<\/code><\/h3>\n<p>\u6b64\u985e\u5225\u4f7f\u7528 JUnit 5 (<code>org.junit.jupiter.api<\/code>) \u4f86\u6e2c\u8a66\u4e09\u500b\u5f71\u50cf\u8655\u7406\u529f\u80fd\u662f\u5426\u6b63\u78ba\uff1a<\/p>\n<table>\n<thead>\n<tr>\n<th>\u6e2c\u8a66\u65b9\u6cd5<\/th>\n<th>\u529f\u80fd\u9a57\u8b49<\/th>\n<th>\u9810\u671f\u8f38\u51fa\u6a94\u6848<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>test_Mirroring()<\/code><\/td>\n<td>\u6c34\u5e73\u93e1\u50cf<\/td>\n<td><code>15088-mirror.png<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>test_Negative()<\/code><\/td>\n<td>\u8272\u5f69\u53cd\u8f49<\/td>\n<td><code>15088-negative.png<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>test_Posterize()<\/code><\/td>\n<td>\u8272\u5f69\u5206\u6bb5<\/td>\n<td><code>15088-poster.png<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>\ud83d\udccc \u6e2c\u8a66\u6d41\u7a0b\u89e3\u6790<\/h3>\n<p>\u6bcf\u500b\u6e2c\u8a66\u65b9\u6cd5\u90fd\u9075\u5faa\u4ee5\u4e0b\u6b65\u9a5f\uff1a<\/p>\n<ol>\n<li>\n<p><strong>\u8f09\u5165\u539f\u59cb\u5f71\u50cf<\/strong>\uff1a<\/p>\n<p>java<\/p>\n<pre><code>Image originalImg = new Image(\"resources\/15088.jpg\");<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u8f09\u5165\u9810\u671f\u7d50\u679c\u5f71\u50cf<\/strong>\uff1a<\/p>\n<p>java<\/p>\n<pre><code>Image expectedImg = new Image(\"resources\/tests\/15088-mirror.png\");<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u5efa\u7acb\u8f49\u63db\u5668\u4e26\u57f7\u884c\u64cd\u4f5c<\/strong>\uff1a<\/p>\n<p>java<\/p>\n<pre><code>ImageTransformer t = new ImageTransformer(originalImg);\nImage outputImage = t.mirror(); \/\/ \u6216 negative(), posterize()<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u6bd4\u5c0d\u7d50\u679c\u662f\u5426\u4e00\u81f4<\/strong>\uff1a<\/p>\n<p>java<\/p>\n<pre><code>assertEquals(expectedImg, outputImage);<\/code><\/pre>\n<\/li>\n<\/ol>\n<h3>\u2705 \u5efa\u8b70\u88dc\u5145\u8207\u5f37\u5316<\/h3>\n<ul>\n<li><strong>\u6e2c\u8a66\u8986\u84cb\u7387<\/strong>\uff1a\u53ef\u52a0\u5165\u908a\u754c\u6e2c\u8a66\uff08\u4f8b\u5982\u7a7a\u767d\u5f71\u50cf\u3001\u6975\u5c0f\u5c3a\u5bf8\u3001\u55ae\u8272\u5f71\u50cf\uff09\u3002<\/li>\n<li><strong>\u932f\u8aa4\u8655\u7406\u6e2c\u8a66<\/strong>\uff1a\u6e2c\u8a66 null \u8f38\u5165\u3001\u7121\u6548\u6a94\u6848\u8def\u5f91\u3001\u7570\u5e38\u683c\u5f0f\u3002<\/li>\n<li><strong>\u8996\u89ba\u9a57\u8b49\u5de5\u5177<\/strong>\uff1a\u82e5 <code>Image.equals()<\/code> \u4f7f\u7528\u50cf\u7d20\u6bd4\u5c0d\uff0c\u53ef\u52a0\u5165\u50cf\u7d20\u5dee\u7570\u8996\u89ba\u5316\u5de5\u5177\u4ee5\u8f14\u52a9\u9664\u932f\u3002<\/li>\n<li><strong>\u6548\u80fd\u6e2c\u8a66<\/strong>\uff1a\u5c0d\u5927\u578b\u5f71\u50cf\u9032\u884c\u8655\u7406\u6642\uff0c\u6e2c\u8a66\u57f7\u884c\u6642\u9593\u8207\u8a18\u61b6\u9ad4\u4f7f\u7528\u3002<\/li>\n<\/ul>\n<p>\u5982\u679c\u4f60\u5e0c\u671b\u6211\u5e6b\u4f60\u88dc\u4e0a <code>mirror()<\/code>\u3001<code>negative()<\/code> \u6216 <code>posterize()<\/code> \u7684\u5be6\u4f5c\uff0c\u6211\u53ef\u4ee5\u63d0\u4f9b\u6a21\u7d44\u5316\u7248\u672c\uff0c\u9644\u4e0a\u4e2d\u82f1\u6587\u8a3b\u89e3\u8207\u6e2c\u8a66\u6848\u4f8b\u3002\u4e5f\u53ef\u4ee5\u5e6b\u4f60\u64b0\u5beb README \u6587\u4ef6\u4f86\u5c55\u793a\u6574\u500b Task1 \u7684\u529f\u80fd\u8207\u6559\u5b78\u6d41\u7a0b\u3002\u8981\u4e0d\u8981\u6211\u5e6b\u4f60\u88dc\u4e0a <code>mirror()<\/code> \u7684\u7a0b\u5f0f\u78bc\u7bc4\u4f8b\uff1f\u6211\u5011\u53ef\u4ee5\u4e00\u6b65\u6b65\u5b8c\u6210\u6574\u500b\u6a21\u7d44\u3002<\/p>\n<pre><code class=\"language-java\">package ca.ubc.ece.cpen221.ip.mp;\n\nimport ca.ubc.ece.cpen221.ip.core.Image;\n\nimport org.junit.jupiter.api.Test;\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\npublic class Task1Tests {\n\n   @Test\n   public void test_Mirroring() {\n       Image originalImg = new Image(&quot;resources\/15088.jpg&quot;);\n       Image expectedImg = new Image(&quot;resources\/tests\/15088-mirror.png&quot;);\n       ImageTransformer t = new ImageTransformer(originalImg);\n       Image outputImage = t.mirror();\n       assertEquals(expectedImg, outputImage);\n   }\n\n   @Test\n   public void test_Negative() {\n       Image originalImg = new Image(&quot;resources\/15088.jpg&quot;);\n       Image expectedImg = new Image(&quot;resources\/tests\/15088-negative.png&quot;);\n       ImageTransformer t = new ImageTransformer(originalImg);\n       Image outputImage = t.negative();\n       assertEquals(expectedImg, outputImage);\n   }\n\n   @Test\n   public void test_Posterize() {\n       Image originalImg = new Image(&quot;resources\/15088.jpg&quot;);\n       Image expectedImg = new Image(&quot;resources\/tests\/15088-poster.png&quot;);\n       ImageTransformer t = new ImageTransformer(originalImg);\n       Image outputImage = t.posterize();\n       assertEquals(expectedImg, outputImage);\n   }\n\n}<\/code><\/pre>\n<h2>8  Task2test<\/h2>\n<pre><code class=\"language-java\">package ca.ubc.ece.cpen221.ip.mp;\n\nimport ca.ubc.ece.cpen221.ip.core.Image;\n\nimport org.junit.jupiter.api.Test;\nimport static org.junit.jupiter.api.Assertions.assertEquals;\n\npublic class Task2Tests {\n\n   @Test\n   public void test_Weathering() {\n       Image originalImg = new Image(&quot;resources\/95006.jpg&quot;);\n       Image expectedImg = new Image(&quot;resources\/tests\/95006-weathered.png&quot;);\n       ImageTransformer t = new ImageTransformer(originalImg);\n       Image outputImage = t.weather();\n       assertEquals(expectedImg, outputImage);\n   }\n}<\/code><\/pre>\n<p>\u9019\u6bb5\u7a0b\u5f0f\u78bc\u662f\u91dd\u5c0d <code>ImageTransformer.weather()<\/code> \u65b9\u6cd5\u7684\u55ae\u5143\u6e2c\u8a66\uff0c\u5c6c\u65bc Task 2 \u7684\u9a57\u8b49\u908f\u8f2f\u3002\u4ee5\u4e0b\u662f\u4e2d\u6587\u89e3\u6790\u8207\u5efa\u8b70\u88dc\u5145\uff1a<\/p>\n<h3>\ud83e\uddea \u6e2c\u8a66\u65b9\u6cd5\uff1a<code>test_Weathering()<\/code><\/h3>\n<p>\u6b64\u6e2c\u8a66\u76ee\u7684\u662f\u78ba\u8a8d\u300c\u98a8\u5316\u6548\u679c\u300d\u662f\u5426\u6b63\u78ba\u5957\u7528\u5728\u5f71\u50cf\u4e0a\u3002<\/p>\n<h4>\ud83d\udccc \u6e2c\u8a66\u6d41\u7a0b\uff1a<\/h4>\n<ol>\n<li>\n<p><strong>\u8f09\u5165\u539f\u59cb\u5f71\u50cf<\/strong>\uff1a<\/p>\n<p>java<\/p>\n<pre><code>Image originalImg = new Image(\"resources\/95006.jpg\");<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u8f09\u5165\u9810\u671f\u98a8\u5316\u5f8c\u5f71\u50cf<\/strong>\uff1a<\/p>\n<p>java<\/p>\n<pre><code>Image expectedImg = new Image(\"resources\/tests\/95006-weathered.png\");<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u5efa\u7acb\u8f49\u63db\u5668\u4e26\u57f7\u884c<\/strong> <code>weather()<\/code> <strong>\u65b9\u6cd5<\/strong>\uff1a<\/p>\n<p>java<\/p>\n<pre><code>ImageTransformer t = new ImageTransformer(originalImg);\nImage outputImage = t.weather();<\/code><\/pre>\n<\/li>\n<li>\n<p><strong>\u6bd4\u5c0d\u7d50\u679c\u662f\u5426\u4e00\u81f4<\/strong>\uff1a<\/p>\n<p>java<\/p>\n<pre><code>assertEquals(expectedImg, outputImage);<\/code><\/pre>\n<\/li>\n<\/ol>\n<h3>\ud83c\udf2b\ufe0f <code>weather()<\/code> \u65b9\u6cd5\u9810\u671f\u884c\u70ba<\/h3>\n<p>\u96d6\u7136\u5c1a\u672a\u5be6\u4f5c\uff0c\u4f46\u6839\u64da\u547d\u540d\u8207\u6e2c\u8a66\u76ee\u7684\uff0c<code>weather()<\/code> \u61c9\u6a21\u64ec\u5f71\u50cf\u7684\u8001\u5316\u6216\u892a\u8272\u6548\u679c\uff0c\u53ef\u80fd\u5305\u62ec\uff1a<\/p>\n<ul>\n<li>\u8272\u5f69\u504f\u79fb\uff08\u4f8b\u5982\u504f\u9ec3\u3001\u504f\u7070\uff09<\/li>\n<li>\u52a0\u5165\u96dc\u8a0a\uff08\u6a21\u64ec\u522e\u75d5\u3001\u7070\u5875\uff09<\/li>\n<li>\u5c0d\u6bd4\u964d\u4f4e\u6216\u6a21\u7cca\u8655\u7406<\/li>\n<\/ul>\n<h3>\u2705 \u5efa\u8b70\u88dc\u5145<\/h3>\n<ul>\n<li><strong>\u591a\u6a23\u5316\u6e2c\u8a66<\/strong>\uff1a\u53ef\u52a0\u5165\u4e0d\u540c\u89e3\u6790\u5ea6\u3001\u8272\u5f69\u98a8\u683c\u7684\u5f71\u50cf\u9032\u884c\u6e2c\u8a66\u3002<\/li>\n<li><strong>\u8996\u89ba\u5dee\u7570\u5bb9\u5fcd\u5ea6<\/strong>\uff1a\u82e5 <code>Image.equals()<\/code> \u662f\u50cf\u7d20\u7d1a\u6bd4\u5c0d\uff0c\u53ef\u80fd\u9700\u52a0\u5165\u5bb9\u5dee\u6a5f\u5236\uff08\u4f8b\u5982\u5141\u8a31\u5fae\u5c0f\u8272\u5dee\uff09\u3002<\/li>\n<li><strong>\u6548\u80fd\u6e2c\u8a66<\/strong>\uff1a\u5c0d\u5927\u578b\u5f71\u50cf\u9032\u884c\u98a8\u5316\u8655\u7406\u6642\uff0c\u6e2c\u8a66\u57f7\u884c\u6642\u9593\u8207\u8a18\u61b6\u9ad4\u4f7f\u7528\u3002<\/li>\n<\/ul>\n<p>\u5982\u679c\u4f60\u5e0c\u671b\u6211\u5e6b\u4f60\u8a2d\u8a08 <code>weather()<\/code> \u7684\u5be6\u4f5c\u908f\u8f2f\uff0c\u6211\u53ef\u4ee5\u63d0\u4f9b\u4e00\u500b\u6a21\u7d44\u5316\u7248\u672c\uff0c\u4f8b\u5982\u4f7f\u7528\u96a8\u6a5f\u96dc\u8a0a\u758a\u52a0\u3001\u8272\u5f69\u504f\u79fb\u77e9\u9663\u6216\u6a21\u7cca\u6ffe\u6ce2\u5668\u3002\u4e5f\u53ef\u4ee5\u5e6b\u4f60\u64b0\u5beb\u4e2d\u82f1\u6587\u8a3b\u89e3\u8207\u6e2c\u8a66\u6848\u4f8b\uff0c\u8b93\u6574\u500b Task 2 \u66f4\u5b8c\u6574\u3001\u53ef\u5c55\u793a\u3002\u8981\u4e0d\u8981\u6211\u5e6b\u4f60\u88dc\u4e0a <code>weather()<\/code> \u7684\u7a0b\u5f0f\u78bc\u7bc4\u4f8b\uff1f\u6211\u5011\u53ef\u4ee5\u4e00\u6b65\u6b65\u5b8c\u6210\u6574\u500b\u6a21\u7d44\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4ee5\u4e0b\u662f\u4f60\u63d0\u4f9b\u7684\u6a21\u7d44\u540d\u7a31\u7684\u4e2d\u6587\u89e3\u91cb\uff0c\u5047\u8a2d\u9019\u662f\u4e00\u500b\u5f71\u50cf\u8655\u7406\u76f8\u95dc\u7684\u8edf\u9ad4\u67b6\u69cb\uff1a \ud83d\udce6 \u6a21\u7d44\u540d\u7a31\u8207\u4e2d\u6587\u8aaa\u660e \u6a21\u7d44\u540d\u7a31 \u4e2d\u6587&#8230; &raquo; <a class=\"read-more-link\" href=\"https:\/\/vm1.go2see.me\/?p=1092\">\u95b1\u8b80\u5168\u6587<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,1],"tags":[],"class_list":["post-1092","post","type-post","status-publish","format-standard","hentry","category-22","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/posts\/1092","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1092"}],"version-history":[{"count":5,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/posts\/1092\/revisions"}],"predecessor-version":[{"id":1094,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/posts\/1092\/revisions\/1094"}],"wp:attachment":[{"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1092"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1092"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1092"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}