Code Optimization

Interesting things in software development and code optimization

Print on Wood - Image overlay


Hello my dear friends,


in this post I will show you how to overlay one image over another image like if you would print an image over wood.

In this example we need two images, one is a wood image and another one is just a photo or whatever image do you like.

To make such effect we will do a few simple steps, here you are:

- create an empty image that will be a result image;

- draw your wood texture over that empty image;

- combine colors of the wood image and a photo, using the following formula c1 * c2 / 255.0;


The main thing here is to multiply each component of colors and divide it by 255.0. You do not need to do anything with alpha,

here is the short code:

for (int y = 0; y < surfWood.Bounds.Height; y++)

{

for (int x = 0; x < surfWood.Bounds.Width; x++)

{

color = surfWood.GetPixel(x, y);

color2 = surfSrc.GetPixel(x, y);

surfWood.SetPixelAsIs((byte)((double)color.R*(double)color2.R/255.0)

,(byte)((double)color.G*(double)color2.G/255.0)

,(byte)((double)color.B*(double)color2.B/255.0)

,color.A

, x, y);

}

}


 the result you will get is like the following:



so looks like you have printed out on a wood plate.


Thank you



1vqHSTrq1GEoEF7QsL8dhmJfRMDVxhv2y



C#.Net - Perspective Image Transform

Hello,


Today, I'm going to share one interesting thing that everyone may need - perspective image transformation.

Its 2D transformation that makes image look like in perspective view like 3D but without any 3D:


So, the main thing there is math. We take an image, specify four points and math will do the trick.

First step is to create and calculate matrices from the new four points:

//original points

Point p1 = new Point(0, 0);

Point p2 = new Point(width, 0);

Point p3 = new Point(width, height);

Point p4 = new Point(0, height);

//create matrix

A = Matrix3x3.Homogenous(p1, p2, p3, p4);

//new points

Point n1 = points[0];

Point n2 = points[1];

Point n3 = points[2];

Point n4 = points[3];

B = Matrix3x3.Homogenous(n1, n2, n3, n4);

A.Inverse();

C = B.MultMat(A);

C.Inverse();

Second step is to go through each pixel on your image and calculate new pixel:

Point ptDest = new Point(0, 0);

PointF ptOriginF = new Point(0, 0);

int iOrigX = 0;

Color pix = new Color();

for (int x = 0; x < width; ++x)

{

for (int y = 0; y < height; ++y)

{

ptDest.X = x;

ptDest.Y = y;

ptOriginF = C.Update(ptDest);

if (ptOriginF.X >= -5 && ptOriginF.X < width && ptOriginF.Y >= -5 && ptOriginF.Y < height)

{


iOrigX = (int)ptOriginF.X; // round to lowest integer

int iOrigY = (int)ptOriginF.Y; // round to lowest integer

double dx = ptOriginF.X - iOrigX;

double dy = ptOriginF.Y - iOrigY;

Point ptOrigin = new Point(iOrigX, iOrigY);

if (dx != 0.0f || dy != 0.0)

{

Color pix1 = Color.FromArgb(0, 255, 255, 255);

Color pix2 = Color.FromArgb(0, 255, 255, 255);

Color pix3 = Color.FromArgb(0, 255, 255, 255);

Color pix4 = Color.FromArgb(0, 255, 255, 255);

//

// Correct square's direction

//

int idx = (dx >= 0.0) ? 1 : -1;

int idy = (dy >= 0.0) ? 1 : -1;


dx = Math.Abs(dx);

dy = Math.Abs(dy);

//

// Get pixels of square

//

if (ptOrigin.X >= 0 && ptOrigin.X < width && ptOrigin.Y >= 0 && ptOrigin.Y < height)

pix1 = src.GetPixel(ptOrigin.X, ptOrigin.Y);

if (ptOrigin.X + idx >= 0 && ptOrigin.X + idx < width && ptOrigin.Y >= 0 && ptOrigin.Y < height)

pix2 = src.GetPixel(ptOrigin.X + idx, ptOrigin.Y);

if (ptOrigin.X >= 0 && ptOrigin.X < width && ptOrigin.Y + idy >= 0 && ptOrigin.Y + idy < height)

pix3 = src.GetPixel(ptOrigin.X, ptOrigin.Y + idy);

if (ptOrigin.X + idx >= 0 && ptOrigin.X + idx < width && ptOrigin.Y + idy >= 0 && ptOrigin.Y + idy < height)

pix4 = src.GetPixel(ptOrigin.X + idx, ptOrigin.Y + idy);

//

// Use bilinear interpolation

//

double r = pix1.R + (pix2.R - pix1.R) * dx + (pix3.R - pix1.R) * dy + (pix1.R - pix2.R - pix3.R + pix4.R) * dx * dy;

double g = pix1.G + (pix2.G - pix1.G) * dx + (pix3.G - pix1.G) * dy + (pix1.G - pix2.G - pix3.G + pix4.G) * dx * dy;

double b = pix1.B + (pix2.B - pix1.B) * dx + (pix3.B - pix1.B) * dy + (pix1.B - pix2.B - pix3.B + pix4.B) * dx * dy;

double a = pix1.A + (pix2.A - pix1.A) * dx + (pix3.A - pix1.A) * dy + (pix1.A - pix2.A - pix3.A + pix4.A) * dx * dy;

pix = Color.FromArgb((byte)a, (byte)r, (byte)g, (byte)b);

}

else

{

pix = src.GetPixel(ptOrigin.X, ptOrigin.Y);

}

dst.SetPixel(ptDest.X, ptDest.Y, pix);

}

}

}

So this is bilinear interpolation is the main thing to transform your image.


Thank you.

PS

will extend this and provide source code if you will request.

PPS

    public class Matrix3x3
    {
        double [,] m_val = new double [3,3];

        public Matrix3x3()
        {
        }
        public Matrix3x3(Point p1, Point p2, Point p3)
        {
            m_val = new double[3, 3];
            m_val[0, 0] = p1.X;
            m_val[0, 1] = p2.X;
            m_val[0, 2] = p3.X;

            m_val[1, 0] = p1.Y;
            m_val[1, 1] = p2.Y;
            m_val[1, 2] = p3.Y;

            m_val[2, 0] = 1.0;
            m_val[2, 1] = 1.0;
            m_val[2, 2] = 1.0;
        }

        public double Determinant()
        {
            double result = 0;
            result = m_val[0, 0] * (m_val[1, 1] * m_val[2, 2] - m_val[1, 2] * m_val[2, 1]);
            result-= m_val[0, 1] * (m_val[1, 0] * m_val[2, 2] - m_val[1, 2] * m_val[2, 0]);
            result+= m_val[0, 2] * (m_val[1, 0] * m_val[2, 1] - m_val[1, 1] * m_val[2, 0]);

            return result;
        }
        public double a(int i, int j)
        {
            return m_val[i-1, j-1];
        }

        public void Inverse()
        {
            double a11 = a(2, 2) * a(3, 3) - a(2, 3) * a(3, 2);
            double a12 = a(2, 1) * a(3, 3) - a(2, 3) * a(3, 1);
            double a13 = a(2, 1) * a(3, 2) - a(2, 2) * a(3, 1);

            double a21 = a(1, 2) * a(3, 3) - a(1, 3) * a(3, 2);
            double a22 = a(1, 1) * a(3, 3) - a(1, 3) * a(3, 1);
            double a23 = a(1, 1) * a(3, 2) - a(1, 2) * a(3, 1);

            double a31 = a(1, 2) * a(2, 3) - a(1, 3) * a(2, 2);
            double a32 = a(1, 1) * a(2, 3) - a(1, 3) * a(2, 1);
            double a33 = a(1, 1) * a(2, 2) - a(1, 2) * a(2, 1);

            double od = 1.0/Determinant();

            m_val[0, 0] = od * a11;
            m_val[0, 1] = -od * a21;
            m_val[0, 2] = od * a31;

            m_val[1, 0] = -od * a12;
            m_val[1, 1] = od * a22;
            m_val[1, 2] = -od * a32;

            m_val[2, 0] = od * a13;
            m_val[2, 1] = -od * a23;
            m_val[2, 2] = od * a33;
        }

        public void MultByVec(double [] vector)
        {
            for (int row = 0; row < 3; ++row)
            {
                m_val[row, 0] *= vector[0];
                m_val[row, 1] *= vector[1];
                m_val[row, 2] *= vector[2];
            }
        }
        public PointD Update(PointD vector)
        {
            double x = a(1, 1) * vector.X + a(1, 2) * vector.Y + a(1, 3) * 1.0;
            double y = a(2, 1) * vector.X + a(2, 2) * vector.Y + a(2, 3) * 1.0;
            double z = a(3, 1) * vector.X + a(3, 2) * vector.Y + a(3, 3) * 1.0;
            //
            PointD result = new PointD();
            result.X = (x / z);
            result.Y = (y / z);
            return result;
        }

        public Matrix3x3 MultMat(Matrix3x3 B)
        {
            Matrix3x3 result = new Matrix3x3();

            result.m_val[0, 0] = a(1, 1) * B.a(1, 1) + a(1, 2) * B.a(2, 1) + a(1, 3) * B.a(3, 1);
            result.m_val[0, 1] = a(1, 1) * B.a(1, 2) + a(1, 2) * B.a(2, 2) + a(1, 3) * B.a(3, 2);
            result.m_val[0, 2] = a(1, 1) * B.a(1, 3) + a(1, 2) * B.a(2, 3) + a(1, 3) * B.a(3, 3);

            result.m_val[1, 0] = a(2, 1) * B.a(1, 1) + a(2, 2) * B.a(2, 1) + a(2, 3) * B.a(3, 1);
            result.m_val[1, 1] = a(2, 1) * B.a(1, 2) + a(2, 2) * B.a(2, 2) + a(2, 3) * B.a(3, 2);
            result.m_val[1, 2] = a(2, 1) * B.a(1, 3) + a(2, 2) * B.a(2, 3) + a(2, 3) * B.a(3, 3);

            result.m_val[2, 0] = a(3, 1) * B.a(1, 1) + a(3, 2) * B.a(2, 1) + a(3, 3) * B.a(3, 1);
            result.m_val[2, 1] = a(3, 1) * B.a(1, 2) + a(3, 2) * B.a(2, 2) + a(3, 3) * B.a(3, 2);
            result.m_val[2, 2] = a(3, 1) * B.a(1, 3) + a(3, 2) * B.a(2, 3) + a(3, 3) * B.a(3, 3);

            return result;
        }

        public static Matrix3x3 Homogenous(Point p1, Point p2, Point p3, Point p4)
        {
            Matrix3x3 Major = new Matrix3x3(p1, p2, p3);
            Matrix3x3 Minor1 = new Matrix3x3(p4, p2, p3);
            Matrix3x3 Minor2 = new Matrix3x3(p1, p4, p3);
            Matrix3x3 Minor3 = new Matrix3x3(p1, p2, p4);
            double MajorD = Major.Determinant();
            double Minor1D = Minor1.Determinant();
            double Minor2D = Minor2.Determinant();
            double Minor3D = Minor3.Determinant();

            double[] coeff = new double[3];
            coeff[0] = Minor1D / MajorD;
            coeff[1] = Minor2D / MajorD;
            coeff[2] = Minor3D / MajorD;
            //
            Major.MultByVec(coeff);

            return Major;
        }
    }





1vqHSTrq1GEoEF7QsL8dhmJfRMDVxhv2y



Bits, bytes and masks

Hello,


Today we are going to learn how to apply mask to any type of data. We will look into mask itself, and apply a mask to an image.

Lets look into the image below to get general idea of mask:


As you can see we took the star mask and an image and got imaged star in output. Cool? :)

Hmm, what is going on and how to do it? Everything is very simple if you have learned my post about bit manipulations.

So, to do it we need the following things:

- bit mask;

- an image;

- go through each byte and apply AND operation for each couple of bytes (actually Int32 in my case as it is much faster).

Here is how:

Int32[] rgba_source = new Int32[256 * 256];

Int32[] rgba_dest = new Int32[256 * 256];

for (int i = 0; i < rgba_source.Length; i++)

{

rgba_dest[i] = rgba_dest[i] & rgba_source[i];

}

Here is the result of masking two images:


That's it, you have got like textured object/figure :).


Now, just imagine where you can use such approach and with which kind of data, as well as other operations like XOR and OR.

In short - it can be used in hash, crypto, visualization algorithms and much more.

One easiest encryption algorithm is just apply XOR for each char of string, for example:

string origin = "hello world";

string encoded = string.Empty;

string decoded = string.Empty;

for (int i = 0; i < origin.Length; i++)

{

encoded += (char)(origin[i] ^ 0x003F);

}

And we will get "WZSSPHPMS[" in the encoded variable, that is equal to hello world but just encoded. To decrypt/decode it, just make the same XOR:

for (int i = 0; i < encoded.Length; i++)

{

decoded += (char)(encoded[i] ^ 0x003F);

}

And you got your "hello world" string back again in the decoded variable.

Think about it and a lot of things you can do with that ;)


Thank you and see you next time.


1vqHSTrq1GEoEF7QsL8dhmJfRMDVxhv2y