/**
        For each pixel location in the new buffer P' (NewX, NewY), do:
            Find corresponding old location, P = W-1.P'
            Validate that this old location lie inside the original image boundary (i.e. 0 ≤ OldX < W,  0  ≤ Old Y < H). Otherwise, set the new empty pixel to 0 and continue to next location.
            If Validated, apply Bilinear Interpolation Algorithm to get the new pixel value, as follows:(Refer to above figure)
                */
        public BufferedImage apply_transformation_matrix_to_bitmap_or_buffer(Matrix _transformations_matrix, BufferedImage _src_img, int _new_width, int _new_height, TextBox _console)
        {
            BufferedImage ret = new BufferedImage(_new_width, _new_height);
            BilinearInterpolation obj_bi_lin_interpol = new BilinearInterpolation();
            for (int i = 0; i < _new_width; i++)
            {
                for (int j = 0; j < _new_height; j++)
                {
                    PointF[] points = {
                                          new PointF(i, j)
                                      };
                    _transformations_matrix.TransformPoints(points);
                    _console.Text += "P = (" + points[0].X + ", " + points[0].Y + ")";
                    _console.Text += Environment.NewLine;
                    _console.Text += "P' = (" + i + ", " + j + ")";
                    _console.Text += Environment.NewLine;

                    Color _color = Color.FromArgb(0);
                    if(points[0].X >= 0 && points[0].X < _src_img.width && points[0].Y >= 0 && points[0].Y < _src_img.height)
                        _color = obj_bi_lin_interpol.calculate(_src_img, points[0].X, points[0].Y);
                    ret.buffer[i, j] = _color;
                }
            }
            return ret;
        }
Beispiel #2
0
        public void run_test(TextBox _console)
        {
            Bitmap bmp = new Bitmap(Image.FromFile("C:/lenna.png"));
            BufferedImage obj_buff_img = new BufferedImage(bmp, _console);

            ImageMatrixTransformations obj_trans = new ImageMatrixTransformations();
            BufferedImage ret = obj_trans.perform_concat_matrices_operations(obj_buff_img, _console);

            Bitmap new_bmp = ret.get_bitmap_object();
            new_bmp.Save("new_lenna.png");
        }
        /**
         * find 4 adjacent pixels
            X1 = floor (OldX)	; X2 = X1 + 1
            Y1 = floor (OldY)	; Y2 = Y1 + 1
            P1 = OrigBuf[X1,Y1] 	; P2 = OrigBuf[X2,Y1]
            P3 = OrigBuf[X1,Y2] 	; P4 = OrigBuf[X2,Y2]
            Calculate X, Y fractions
            Xfraction = OldX – X1
            Yfraction = OldY – Y1
            Interpolate in X-Direction
            Z1 = P1 × (1 – Xfraction) + P2 × Xfraction
            Z2 = P3 × (1 – Xfraction) + P4 × Xfraction
            Interpolate in Y-Direction
            NewPixel = Z1 × (1 – Yfraction) + Z2 × Yfraction
         */
        public Color calculate(BufferedImage _original_buffer, float _old_x, float _old_y)
        {
            int new_red, new_green, new_blue;
            Color ret;
            int x_1 = (int)Math.Floor(_old_x);
            int x_2 = x_1 + 1;

            int y_1 = (int)Math.Floor(_old_y);
            int y_2 = y_1 + 1;

            Color p_1 = _original_buffer.buffer[x_1, y_1];
            Color p_2 = _original_buffer.buffer[x_2, y_2];
            Color p_3 = _original_buffer.buffer[x_1, y_2];
            Color p_4 = _original_buffer.buffer[x_2, y_2];

            float x_fraction = _old_x - x_1;
            float y_fraction = _old_y - y_1;

            // Interpolate in X-Direction
            // Red
            int r_1 = (int)Math.Floor(p_1.R * (1 - x_fraction) + p_2.R * x_fraction);
            int r_2 = (int)Math.Floor(p_3.R * (1 - x_fraction) + p_4.R * x_fraction);

            // Green
            int g_1 = (int)Math.Floor(p_1.G * (1 - x_fraction) + p_2.G * x_fraction);
            int g_2 = (int)Math.Floor(p_3.G * (1 - x_fraction) + p_4.G * x_fraction);

            // Blue
            int b_1 = (int)Math.Floor(p_1.B * (1 - x_fraction) + p_2.B * x_fraction);
            int b_2 = (int)Math.Floor(p_3.B * (1 - x_fraction) + p_4.B * x_fraction);

            // Interpolate in Y-Direction
            new_red = (int)Math.Floor(r_1 * (1 - y_fraction) + r_2 * y_fraction);
            new_green = (int)Math.Floor(g_1 * (1 - y_fraction) + g_2 * y_fraction);
            new_blue = (int)Math.Floor(b_1 * (1 - y_fraction) + b_2 * y_fraction);

            ret = Color.FromArgb(new_red, new_green, new_blue);

            return ret;
        }
        /**
        You can use this matrix as follows:
            1 - Create new object with identity matrix (empty constructor)
            2 - Apply a set of transformations that you want to this matrix
            3 - Transform the four corners of the original image to calculate
            4 - The min X and min Y of the transformed image
            5 - The width & height of the new image buffer
            6 - Translate this matrix by (- min X, - min Y)
            7 - Invert the matrix
            8 - Use the inverted version to reverse transform all new locations in the new image buffer
        **/
        public BufferedImage perform_concat_matrices_operations(BufferedImage _src_img, TextBox _console, float _shear_x = (float)0, float _shear_y = (float)0, float _scale_x = (float)1, float _scale_y = (float)1, float _rotate_theta = (float)0)
        {
            BufferedImage ret;
            // 1 - Create new object with identity matrix (empty constructor)
            Matrix transformations_matrix = new Matrix();
            // 2 - Apply a set of transformations that you want to this matrix
            transformations_matrix.Rotate(_rotate_theta);
            transformations_matrix.Scale(_scale_x, _scale_y);
            transformations_matrix.Shear(_shear_x, _shear_y);
            // 3 - Transform the four corners of the original image to calculate
            /**
             * To get the size of the new (destination) image,
             * apply the forward mapping to the four corners of the original image
             * ([0,0], [W-1,0], [0,H-1], [W-1,H-1])
             * to get their new locations.
             * Then use these new four locations to get the width and height of the destination image
             * (e.g. to get new width:
             * find min X & max X of the four new points and subtract them,
             * do the same for Y to get the new height)
             */
            Point[] corner_points = {
                                        new Point(0, 0),
                                        new Point(_src_img.width - 1, 0),
                                        new Point(0, _src_img.height - 1),
                                        new Point(_src_img.width - 1, _src_img.height - 1)
                                    };

            transformations_matrix.TransformPoints(corner_points);

            int min_x = find_min_x(corner_points);
            int min_y = find_min_y(corner_points);

            int max_x = find_max_x(corner_points);
            int max_y = find_max_y(corner_points);

            int new_width = max_x - min_x;
            int new_height = max_y - min_y;

            _console.Text += "Min X = ";
            _console.Text += min_x;
            _console.Text += Environment.NewLine;

            _console.Text += "Min Y = ";
            _console.Text += min_y;
            _console.Text += Environment.NewLine;

            _console.Text += "Max X = ";
            _console.Text += max_x;
            _console.Text += Environment.NewLine;

            _console.Text += "Max Y = ";
            _console.Text += max_y;
            _console.Text += Environment.NewLine;

            _console.Text += "New Width = ";
            _console.Text += new_width;
            _console.Text += Environment.NewLine;

            _console.Text += "New Height = ";
            _console.Text += new_height;
            _console.Text += Environment.NewLine;

            // 4 - The min X and min Y of the transformed image
            /**
             * To make the transformed image totally fit inside the buffer, a translation with (- min X, - min Y) should be appended to the original transformation matrix (W) before inverting it.
             */

            // 6 - Translate this matrix by (- min X, - min Y)
            transformations_matrix.Translate(-min_x, -min_y);

            // 7 - Invert the matrix
            transformations_matrix.Invert();

            // 8 - Use the inverted version to reverse transform all new locations in the new image buffer
            ret = apply_transformation_matrix_to_bitmap_or_buffer(transformations_matrix, _src_img, new_width, new_height, _console);
            return ret;
        }