- Home
- General
- General Chat
FransIsAGeek
Posts
Posts: 719
Joined: 04-Feb-2004
Joined: 04-Feb-2004
# Posted on: 02-Nov-2005 14:37:38
i concur, however the about box is pretty cool. i guess that puts me into the same boat.
Posts: 39800
Joined: 17-Aug-2003
Joined: 17-Aug-2003
# Posted on: 02-Nov-2005 15:48:08
0ld sk00l d3mosc33n
Here, for kicks: (.NET 2.0)
// MainForm.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
namespace CSRotoZoomer
{
public partial class MainForm : Form
{
#region Members
private int _imageWidth, _imageHeight, _zoomCounter, _zoomInMax, _zoomOutMax;
private Bitmap _image;
private bool _zoomIn;
private double _gamma, _deltaGamma, _xZoomDelta, _yZoomDelta, _imageWidthD, _imageHeightD;
// coordinate source.
double[] _xSourceCoords ={ -128, 128, -128 };
double[] _ySourceCoords ={ -64, -64, 64 };
// coordinate destination. (for drawing).
double[] _xDestinationCoords ={ -128, 128, -128 };
double[] _yDestinationCoords ={ -64, -64, 64 };
uint[] _sourcePixels;
#endregion
/// <summary>
/// CTor
/// </summary>
public MainForm()
{
InitializeComponent();
// be sure this dialog uses double buffered rendering
this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true );
// initialize our parameters.
_zoomCounter = 0;
_zoomIn = false;
// deltaGamma value, controls rotation.
_deltaGamma = 2.0;
// deltas for x and y zooming. If they're not the same the image gets stretched.
_xZoomDelta = 2.0;
_yZoomDelta = 1.0;
// zoom counter values when the zoom action (in/out) will swap
_zoomInMax = 200;
_zoomOutMax = 300;
}
private void openImageToolStripMenuItem_Click( object sender, EventArgs e )
{
DialogResult result = _openImageDialog.ShowDialog( this );
if( result != DialogResult.OK )
{
return;
}
// load bitmap.
_image = new Bitmap( _openImageDialog.FileName );
_imageWidth = _image.Width;
_imageHeight = _image.Height;
_imageWidthD = (double)_imageWidth;
_imageHeightD = (double)_imageHeight;
_sourcePixels = new uint[_imageWidth * _imageHeight];
if( _xZoomDelta != 0 )
{
_zoomInMax = (int)(((_imageWidthD / 2.0) / _xZoomDelta) - 10.0);
}
_zoomOutMax = _zoomInMax * 5;
_yZoomDelta = (_imageHeightD / _imageWidth) * _xZoomDelta;
// read the initial pixels into the srcpixel array. This makes it possible to perform an in-place rendering to avoid memory trashing
BitmapData srcData = _image.LockBits( new Rectangle( 0, 0, _imageWidth, _imageHeight ), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb );
unsafe
{
uint* pSrc = (uint*)srcData.Scan0;
for( int i = 0; i < _imageHeight; i++ )
{
for( int j = 0; j < _imageWidth; j++ )
{
_sourcePixels[(i * _imageWidth) + j] = pSrc[(i * _imageWidth) + j];
}
}
}
_image.UnlockBits( srcData );
// init coord arrays for the three points we're using to read the source pixels
// A ---------- B
// |
// |
// |
// |
// C
double halfWidth = _imageWidthD / 2.0;
_xSourceCoords[0] = -halfWidth;
_xSourceCoords[1] = halfWidth;
_xSourceCoords[2] = -halfWidth;
_xDestinationCoords[0] = -halfWidth;
_xDestinationCoords[1] = halfWidth;
_xDestinationCoords[2] = -halfWidth;
double halfHeight = _imageHeightD / 2.0;
_ySourceCoords[0] = -halfHeight;
_ySourceCoords[1] = -halfHeight;
_ySourceCoords[2] = halfHeight;
_yDestinationCoords[0] = -halfHeight;
_yDestinationCoords[1] = -halfHeight;
_yDestinationCoords[2] = halfHeight;
_animTimer.Start();
}
private void _animTimer_Tick( object sender, System.EventArgs e )
{
Zoom();
Rotate();
Animate();
}
private void Zoom()
{
if( _zoomIn )
{
for( int i = 0; i < 3; i++ )
{
if( _xSourceCoords[i] < 0 )
{
_xSourceCoords[i] += _xZoomDelta;
}
else
{
_xSourceCoords[i] -= _xZoomDelta;
}
if( _ySourceCoords[i] < 0 )
{
_ySourceCoords[i] += _yZoomDelta;
}
else
{
_ySourceCoords[i] -= _yZoomDelta;
}
}
_zoomCounter++;
if( _zoomCounter > _zoomInMax )
{
_zoomIn = false;
}
}
else
{
for( int i = 0; i < 3; i++ )
{
if( _xSourceCoords[i] < 0 )
{
_xSourceCoords[i] -= _xZoomDelta;
}
else
{
_xSourceCoords[i] += _xZoomDelta;
}
if( _ySourceCoords[i] < 0 )
{
_ySourceCoords[i] -= _yZoomDelta;
}
else
{
_ySourceCoords[i] += _yZoomDelta;
}
}
_zoomCounter--;
if( _zoomCounter < -_zoomOutMax )
{
_zoomIn = true;
}
}
label1.Text = _zoomCounter.ToString();
}
private void Animate()
{
double xa = _xDestinationCoords[0];
double xb = _xDestinationCoords[1];
double xc = _xDestinationCoords[2];
double ya = _yDestinationCoords[0];
double yb = _yDestinationCoords[1];
double yc = _yDestinationCoords[2];
double xab_delta = (xb - xa) / _imageWidthD;
double yab_delta = (yb - ya) / _imageWidthD;
double xac_delta = (xc - xa) / _imageHeightD;
double yac_delta = (yc - ya) / _imageHeightD;
// transpose the rotating centre to the middle of the picture.
double x_off = xa + (_imageWidthD * 0.5);
double y_off = ya + (_imageHeightD * 0.5);
BitmapData imageDst = _image.LockBits( new Rectangle( 0, 0, _imageWidth, _imageHeight ), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb );
System.IntPtr scan0 = imageDst.Scan0;
unsafe
{
uint* pDest = (uint*)scan0;
for( int i = 0; i < _imageHeight; i++ )
{
for( int j = 0; j < _imageWidth; j++ )
{
int readX = (int)x_off;
int readY = (int)y_off;
if( readX < 0 )
{
readX = (_imageWidth - 1) - (-readX % (_imageWidth - 1));
}
if( readY < 0 )
{
readY = (_imageHeight - 1) - (-readY % (_imageHeight - 1));
}
if( readX >= _imageWidth )
{
readX = 0 + (readX % (_imageWidth - 1));
}
if( readY >= _imageHeight )
{
readY = 0 + (readY % (_imageHeight - 1));
}
pDest[0] = _sourcePixels[(readY * _imageWidth) + readX];
x_off += xab_delta;
y_off += yab_delta;
pDest++;
}
double iD = (double)i;
x_off = xa + (iD * (xac_delta - 0.002 * iD)) + (_imageWidthD * 0.5);
y_off = ya + (iD * (yac_delta + 0.001 * iD)) + (_imageHeightD * 0.5);
}
}
_image.UnlockBits( imageDst );
_renderCanvas.Image = _image;
}
public void Rotate()
{
// first update the angle. only gamma is interesting...
_gamma = (_gamma + _deltaGamma) % 360;
double gammaRad = (_gamma / 360) * 2 * Math.PI;
// get the sin and cos of the angles
double sinG = Math.Sin( gammaRad );
double cosG = Math.Cos( gammaRad );
// now rotate the coords...
for( int i = 0; i < 3; i++ )
{
double yn = _ySourceCoords[i];
double xn = _xSourceCoords[i];
_xDestinationCoords[i] = (xn * cosG) - (yn * sinG);
_yDestinationCoords[i] = (yn * cosG) + (xn * sinG);
}
}
}
}
Now put a picture box on a form, a timer (_animTimer) and an openfiledialog, and off you go!
Connect the timer's event to _animTimer_Tick and set the timer to 20ms