Core Optical, Inc.
Resampler RotateChannelInPlace Method Industrial Strength, Scientific Grade
Rotates the data by the specified angle in-place, cropping regions that rotate outside of the image bounds.

Namespace: PrecisionImage.Resampling
Assembly: PrecisionImage (in PrecisionImage.dll) Version: 2.0.0.0 (2.0.0.0)
Syntax

public void RotateChannelInPlace(
	SourceData sourceData,
	int sourceChannel,
	double rotationAngle,
	double originRow,
	double originColumn,
	ResamplingKernel kernel
)

Parameters

sourceData
Type: PrecisionImage SourceData
A SourceData type containing the data to rotate.
sourceChannel
Type: OnlineSystem Int32
An OnlineInt32 type indicating the channel containing the data to resample.
rotationAngle
Type: OnlineSystem Double
A OnlineDouble type indicating the angle to rotate in degrees. Value must be less than 90.0 and greater than -90.0.
originRow
Type: OnlineSystem Double
A OnlineDouble indicating the row index of the origin of the rotation.
originColumn
Type: OnlineSystem Double
A OnlineDouble indicating the column index of the origin of the rotation.
kernel
Type: PrecisionImage.Resampling ResamplingKernel
A ResamplingKernel type that indicates the kernel to use during the resampling operation.
Exceptions

Remarks

This method applies a pure rotation (i.e. no scale change) to the data in the specified channel of sourceData and stores the result in-place, overwriting the original data. Since the dimensions of the sourceData object do not change as a result of the operation, any portion of the data that falls outside the bounds of the image as a result of the rotation will be cropped. A positive value for rotationAngle indicates a counter-clockwise rotation whereas a negative value indicates clockwise rotation.

Examples

This first example rotates a color image counterclockwise by 35.5 degrees:

using PrecisionImage;
using PrecisionImage.Visualization;
using PrecisionImage.Resampling;

// Load the image and display: 
Uri imageUri                   = new Uri("LenaColor256.tif", UriKind.Relative);
TiffBitmapDecoder imageDecoder = new TiffBitmapDecoder(imageUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource sourceImage       = imageDecoder.Frames[0];
SourceData sourceData          = new SourceData(sourceImage, GammaEncoding.None);

// Avoid autoscaling the channels by instantiating a new OutputWindowing object 
// with the min max set to the initial range extents for data (0 - 1): 
OutputWindowing outputLevels = new OutputWindowing();
for (Int32 channel = 0; channel < sourceData.NumberOfChannels; channel++)
{
    outputLevels.AddChannelWindow(0, 1, channel);
}

// Display the color image in the Image control using the full range output levels (0-1):
image1.Source = sourceData.GetBitmapSource(outputLevels, GammaEncoding.None);

// Compute the row/column indices of the rotation origin. Use the image center: 
Int32 LastRowIndex       = sourceData.Rows - 1;
Int32 LastColumnIndex    = sourceData.Columns - 1;
Double OriginRowIndex    = (Double)LastRowIndex * 0.5;
Double OriginColumnIndex = (Double)LastColumnIndex * 0.5;

// Choose a rotation angle: 
Double RotationAngle = 35.5;

// Instantiate a Resampler: 
Resampler resampler = new Resampler();

// Loop through the image channels and rotate: 
for (Int32 channel = 0; channel < sourceData.NumberOfChannels; channel++)
{
   resampler.RotateChannelInPlace(sourceData, channel, RotationAngle, OriginRowIndex, OriginColumnIndex, new MitchellNetravaliKernel());
}

// Display the result in the Image control:
image2.Source = sourceData.GetBitmapSource(outputLevels, GammaEncoding.None);

The following are the output images from this example:

The second examples rotates an image without clipping by first copying the source data into a larger data container and then rotating by 45 degrees counter-clockwise about the data center:

using PrecisionImage;
using PrecisionImage.Visualization;
using PrecisionImage.Resampling;

// Load the image and display: 
Uri imageUri                   = new Uri("LenaColor256.tif", UriKind.Relative);
TiffBitmapDecoder imageDecoder = new TiffBitmapDecoder(imageUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource sourceImage       = imageDecoder.Frames[0];
SourceData sourceData          = new SourceData(sourceImage, GammaEncoding.None);

// Display the image in the Image control:
image1.Source = sourceData.GetChannelImage(GrayBitDepth.EightBit, 0, GammaEncoding.None);

// Compute the target data size so that no clipping occurs regardless 
// of rotation angle: 
Int32 Width   = sourceData.Columns * sourceData.Columns;
Int32 Height  = sourceData.Rows * sourceData.Rows;
Int32 newSize = (Int32)Math.Round(Math.Sqrt(Width + Height), MidpointRounding.AwayFromZero);

// Instantiate a SourceData object of these new dimensions: 
SourceData targetData = new SourceData(newSize, newSize, 1);

// Instantiate a Resampler object: 
Resampler resampler = new Resampler();

// Instantiate a resampling kernel to use for the operations: 
CatmullRomKernel kernel = new CatmullRomKernel();

// Copy the original data into the upper left corner of the new data object: 
Int32Rect sourceRect = new Int32Rect(0, 0, sourceData.Columns, sourceData.Rows);
sourceData.CopyDataRegion(0, sourceRect, targetData, 0, 0, 0);

// Translate this data in-place to the center of the data field: 
Double xTranslation = (targetData.Columns - sourceData.Columns) * 0.5;
Double yTranslation = (targetData.Rows - sourceData.Rows) * 0.5;
resampler.TranslateData(targetData, 0, targetData, 0, xTranslation, yTranslation, kernel);

// Rotate the data counter-clockwise about its center by 45 degrees:
resampler.RotateChannelInPlace(targetData, 0, 45.0, (targetData.Rows - 1) * 0.5, (targetData.Columns - 1) * 0.5, kernel);

// Display the result, scaling the image to the original source data min/max value range: 
OutputWindowing outputLevel = new OutputWindow(sourceData.GetCurrentMinValue(0), sourceData.GetCurrentMaxValue(0), 0);
image2.Source = targetData.GetChannelImage(GrayBitDepth.EightBit, 0, outputWindowing: outputLevel);

The following are the output images from this example:

See Also