## Posts Tagged 'Shear Algorithm'

### Article Purpose

This article is focussed on illustrating the steps required in performing an . All of the concepts explored have been implemented by means of raw pixel data processing, no conventional drawing methods, such as GDI, are required.

Rabbit: Shear X 0.4, Y 0.4

### Using the Sample Application

article features a based sample application which is included as part of the accompanying sample source code. The concepts explored in this article can be illustrated in a practical implementation using the sample application.

The sample application enables a user to load source/input from the local system when clicking the Load Image button. In addition users are also able to save output result to the local file system by clicking the Save Image button.

Image can be applied to either X or Y, or both X and Y pixel coordinates. When using the sample application the user has option of adjusting Shear factors, as indicated on the user interface by the numeric up/down controls labelled Shear X and Shear Y.

The following image is a screenshot of the Image Transform Shear Sample Application in action:

Rabbit: Shear X -0.5, Y -0.25

### Image Shear Transformation

A good definition of the term can be found on the Wikipedia :

In , a shear mapping is a that displaces each point in fixed direction, by an amount proportional to its signed distance from a line that is to that direction.[1] This type of mapping is also called shear transformation, transvection, or just shearing

A can be applied as a horizontal shear, a vertical shear or as both. The algorithms implemented when performing a can be expressed as follows:

Horizontal Shear Algorithm

Vertical Shear Algorithm

The algorithm description:

• Shear(x) : The result of a horizontal – The calculated X-Coordinate representing a .
• Shear(y) : The result of a vertical – The calculated Y-Coordinate representing a .
• σ : The lower case version of the Greek alphabet letter Sigma – Represents the Shear Factor.
• x : The X-Coordinate originating from the source/input – The horizontal coordinate value intended to be sheared.
• y : The Y-Coordinate originating from the source/input – The vertical coordinate value intended to be sheared.
• H : Source height in pixels.
• W : Source width in pixels.

Note: When performing a implementing both the horizontal and vertical planes each coordinate plane can be calculated using a different shearing factor.

The algorithms have been adapted in order to implement a middle pixel offset by means of subtracting the product of the related plane boundary and the specified Shearing Factor, which will then be divided by a factor of two.

Rabbit: Shear X 1.0, Y 0.1

### Implementing a Shear Transformation

The sample source code performs through the implementation of the ShearXY and ShearImage.

The ShearXY targets the structure. The algorithms discussed in the previous sections have been implemented in this function from a C# perspective. The definition as illustrated by the following code snippet:

```public static Point ShearXY(this Point source, double shearX,
double shearY,
int offsetX,
int offsetY)
{
Point result = new Point();

result.X = (int)(Math.Round(source.X + shearX * source.Y));
result.X -= offsetX;

result.Y = (int)(Math.Round(source.Y + shearY * source.X));
result.Y -= offsetY;

return result;
} ```

Rabbit: Shear X 0.0, Y 0.5

The ShearImage targets the class. This method expects as parameter values a horizontal and a vertical shearing factor. Providing a shearing factor of zero results in no shearing being implemented in the corresponding direction. The definition as follows:

```public static Bitmap ShearImage(this Bitmap sourceBitmap,
double shearX,
double shearY)
{
BitmapData sourceData =
sourceBitmap.LockBits(new Rectangle(0, 0,
sourceBitmap.Width, sourceBitmap.Height),
PixelFormat.Format32bppArgb);

byte[] pixelBuffer = new byte[sourceData.Stride *
sourceData.Height];

byte[] resultBuffer = new byte[sourceData.Stride *
sourceData.Height];

Marshal.Copy(sourceData.Scan0, pixelBuffer, 0,
pixelBuffer.Length);

sourceBitmap.UnlockBits(sourceData);

int xOffset = (int )Math.Round(sourceBitmap.Width *
shearX / 2.0);

int yOffset = (int )Math.Round(sourceBitmap.Height *
shearY / 2.0);

int sourceXY = 0;
int resultXY = 0;

Point sourcePoint = new Point();
Point resultPoint = new Point();

Rectangle imageBounds = new Rectangle(0, 0,
sourceBitmap.Width,
sourceBitmap.Height);

for (int row = 0; row < sourceBitmap.Height; row++)
{
for (int col = 0; col < sourceBitmap.Width; col++)
{
sourceXY = row * sourceData.Stride + col * 4;

sourcePoint.X = col;
sourcePoint.Y = row;

if (sourceXY >= 0 &&
sourceXY + 3 < pixelBuffer.Length)
{
resultPoint = sourcePoint.ShearXY(shearX,
shearY, xOffset, yOffset);

resultXY = resultPoint.Y * sourceData.Stride +
resultPoint.X * 4;

if (imageBounds.Contains(resultPoint) &&
resultXY >= 0)
{
if (resultXY + 6 <= resultBuffer.Length)
{
resultBuffer[resultXY + 4] =
pixelBuffer[sourceXY];

resultBuffer[resultXY + 5] =
pixelBuffer[sourceXY + 1];

resultBuffer[resultXY + 6] =
pixelBuffer[sourceXY + 2];

resultBuffer[resultXY + 7] = 255;
}

if (resultXY - 3 >= 0)
{
resultBuffer[resultXY - 4] =
pixelBuffer[sourceXY];

resultBuffer[resultXY - 3] =
pixelBuffer[sourceXY + 1];

resultBuffer[resultXY - 2] =
pixelBuffer[sourceXY + 2];

resultBuffer[resultXY - 1] = 255;
}

if (resultXY + 3 < resultBuffer.Length)
{
resultBuffer[resultXY] =
pixelBuffer[sourceXY];

resultBuffer[resultXY + 1] =
pixelBuffer[sourceXY + 1];

resultBuffer[resultXY + 2] =
pixelBuffer[sourceXY + 2];

resultBuffer[resultXY + 3] = 255;
}
}
}
}
}

Bitmap resultBitmap = new Bitmap(sourceBitmap.Width,
sourceBitmap.Height);

BitmapData resultData =
resultBitmap.LockBits(new Rectangle(0, 0,
resultBitmap.Width, resultBitmap.Height),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb);

Marshal.Copy(resultBuffer, 0, resultData.Scan0,
resultBuffer.Length);

resultBitmap.UnlockBits(resultData);

return resultBitmap;
} ```

Rabbit: Shear X 0.5, Y 0.0

### Sample Images

This article features a number of sample images. All featured images have been licensed allowing for reproduction.

The sample images featuring the image of an Eastern Cottontail Rabbit has been released into the public domain by its author. The original image can be downloaded from .

The sample images featuring the image of a Mountain Cottontail Rabbit is in the public domain in the United States because it is a work prepared by an officer or employee of the United States Government as part of that person’s official duties under the terms of Title 17, Chapter 1, Section 105 of the US Code. The original image can be downloaded from .

Rabbit: Shear X 1.0, Y 0.0

Rabbit: Shear X 0.5, Y 0.1

Rabbit: Shear X -0.5, Y -0.25

Rabbit: Shear X -0.5, Y 0.0

Rabbit: Shear X 0.25, Y 0.0

Rabbit: Shear X 0.50, Y 0.0

Rabbit: Shear X 0.0, Y 0.5

Rabbit: Shear X 0.0, Y 0.25

Rabbit: Shear X 0.0, Y 1.0

### Related Articles and Feedback

Feedback and questions are always encouraged. If you know of an alternative implementation or have ideas on a more efficient implementation please share in the comments section.

I’ve published a number of articles related to imaging and images of which you can find URL links here:

## Blog Stats

• 825,928 hits

Join 228 other followers