"Rotating" an image...

A

asognoth

Hi...

Does anybody have a clue how to solve this problem?

the task is to change the following method in that manner that it
draws the (calculated) image form left to right instead of from top
to bottom. The image is actually a waterfall model of sound data.

I tried desperatly, but I don't see how to swap the x and y
coordinates.
Anybody got a hint?

Here is the method:

unsafe private void DrawWaterfall(ref Graphics g, int W, int
H)
{
bool MOX = false;
float[] data = new float[W]; // array of points to
display
double slope = 0.0; // samples to process per pixel
int num_samples = 0; // number of samples to process
int start_sample_index = 0; // index to begin looking at samples
int low = 0;
int high = 0;
display_max_y = Int32.MinValue;

if(!MOX)
{
low = DttSP.RXDisplayLow;
high = DttSP.RXDisplayHigh;
}
else
{
low = DttSP.TXDisplayLow;
high = DttSP.TXDisplayHigh;
}

int yRange = spectrum_grid_max - spectrum_grid_min;

float[] a = new float[32768];

my_con.dsp_display_mutex.WaitOne();
fixed(float* ptr =
&a[0])DttSP.GetSpectrum(ptr);
my_con.dsp_display_mutex.ReleaseMutex();

if(average_display)
{
if(average_buffer[0] == CLEAR_FLAG)
{
for(int i=0; i<32768; i++)
average_buffer = a;
}
else
{
for(int i=0; i<32768; i++)
average_buffer = a =
(float)(a*average_mult_samp
+average_buffer*average_mult_avg);
}
}

num_samples = (high - low);

start_sample_index = (32768>>1)
+(int)((low * 32768) / DttSP.SampleRate);
num_samples = (int)((high - low) * 32768 /
DttSP.SampleRate);

if (start_sample_index < 0)
start_sample_index = 0;
if ((num_samples - start_sample_index) >
(32768+1))
num_samples = 32768-start_sample_index;

slope = (double)num_samples/(double)W;
for(int i=0; i<H; i++)
{
float max = float.MinValue;
int start =
start_sample_index+(int)Math.Floor(i*slope);
int finish =
start_sample_index+(int)Math.Floor((i+1)*slope);
if (start == finish)
{
max = a[start];
}
else
for(int j=start; j<finish; j++)
max = Math.Max(max, a[j]);

max = max + display_cal[20] + gain_correction +
att_correction;

if(max > display_max_y)
{
display_max_y = max;
display_max_x = i;
}

//data =
-(int)(Math.Floor(max*H/yRange));
data =max;
}


/**************************************************************************/
BitmapData bitmapData = waterfall_bmp.LockBits(
new Rectangle(0, 0, waterfall_bmp.Width,
waterfall_bmp.Height),
ImageLockMode.ReadWrite,
waterfall_bmp.PixelFormat);

int pixel_size = 3;
byte* column = null;

// first scroll image
int total_size = bitmapData.Stride * bitmapData.Height; // find
buffer size
byte[] buffer = new byte[total_size]; // create
buffer
Marshal.Copy(bitmapData.Scan0, buffer, 0, total_size); //
copy bitmap to buffer
Marshal.Copy( buffer, 0,
new
IntPtr((int)bitmapData.Scan0+bitmapData.Stride), //
slide memory and copy back
total_size - bitmapData.Stride);
buffer = null;

row = (byte *)bitmapData.Scan0;

/***********************************************************************************/

// draw new data
for(int i=0; i<W; i++) // for each pixel in the new line
{
int R, G, B;
if(data <= waterfall_low_threshold) // if
less than low threshold use low color
{
R = waterfall_low_color.R;
G = waterfall_low_color.G;
B = waterfall_low_color.B;
}
else if(data >= waterfall_high_threshold) //
if more than high threshold use high color
{
R = waterfall_high_color.R;
G = waterfall_high_color.G;
B = waterfall_high_color.B;
}
else // use a color between high and low
{
float percent = (data -
waterfall_low_threshold)/(waterfall_high_threshold -
waterfall_low_threshold);
if(percent <= 0.5) // use a gradient between low and
mid colors
{
percent *= 2;

R = (int)((1-percent)*waterfall_low_color.R +
percent*waterfall_mid_color.R);
G = (int)((1-percent)*waterfall_low_color.G +
percent*waterfall_mid_color.G);
B = (int)((1-percent)*waterfall_low_color.B +
percent*waterfall_mid_color.B);
}
else // use a gradient between mid and high colors
{

percent = (float)(percent-0.5)*2;

R = (int)((1-percent)*waterfall_mid_color.R +
percent*waterfall_high_color.R);
G = (int)((1-percent)*waterfall_mid_color.G +
percent*waterfall_high_color.G);
B = (int)((1-percent)*waterfall_mid_color.B +
percent*waterfall_high_color.B);
}
}

// set pixel color
row[i*pixel_size + 0] = (byte)B; // set color in
memory
row[i*pixel_size + 1] = (byte)G;
row[i*pixel_size + 2] = (byte)R;
}



waterfall_bmp.UnlockBits(bitmapData);
g.DrawImageUnscaled(waterfall_bmp, 0, 16); // draw the image
on the background

waterfall_counter++;


// draw long cursor
if(long_crosshair)
{
g.DrawLine(new Pen(grid_text_color), display_cursor_x,
0, display_cursor_x, H);
g.DrawLine(new Pen(grid_text_color), 0,
display_cursor_y, W, display_cursor_y);
}
if(display_high_swr)
g.DrawString( "High SWR", new
Font("Arial", 14, FontStyle.Bold),
new SolidBrush(Color.Red), 245, 20);
}


*-----------------------*
Posted at:
www.GroupSrv.com
*-----------------------*
 
B

Bob Powell [MVP]

Try this..
waterfall_bmp.UnlockBits(bitmapData);
Matrix mx=new Matrix(1,0,0,1,0,waterfall.bmp.Width);
mx.Rotate(-90, MatrixOrder.Prepend);
g.Transform=mx;
g.DrawImageUnscaled(waterfall_bmp, 0, 0); // draw the image on the
background

maybe you'll need to fiddle with final position
--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.





asognoth said:
Hi...

Does anybody have a clue how to solve this problem?

the task is to change the following method in that manner that it
draws the (calculated) image form left to right instead of from top
to bottom. The image is actually a waterfall model of sound data.

I tried desperatly, but I don't see how to swap the x and y
coordinates.
Anybody got a hint?

Here is the method:

unsafe private void DrawWaterfall(ref Graphics g, int W, int
H)
{
bool MOX = false;
float[] data = new float[W]; // array of points to
display
double slope = 0.0; // samples to process per pixel
int num_samples = 0; // number of samples to process
int start_sample_index = 0; // index to begin looking at samples
int low = 0;
int high = 0;
display_max_y = Int32.MinValue;

if(!MOX)
{
low = DttSP.RXDisplayLow;
high = DttSP.RXDisplayHigh;
}
else
{
low = DttSP.TXDisplayLow;
high = DttSP.TXDisplayHigh;
}

int yRange = spectrum_grid_max - spectrum_grid_min;

float[] a = new float[32768];

my_con.dsp_display_mutex.WaitOne();
fixed(float* ptr =
&a[0])DttSP.GetSpectrum(ptr);
my_con.dsp_display_mutex.ReleaseMutex();

if(average_display)
{
if(average_buffer[0] == CLEAR_FLAG)
{
for(int i=0; i<32768; i++)
average_buffer = a;
}
else
{
for(int i=0; i<32768; i++)
average_buffer = a =
(float)(a*average_mult_samp
+average_buffer*average_mult_avg);
}
}

num_samples = (high - low);

start_sample_index = (32768>>1)
+(int)((low * 32768) / DttSP.SampleRate);
num_samples = (int)((high - low) * 32768 /
DttSP.SampleRate);

if (start_sample_index < 0)
start_sample_index = 0;
if ((num_samples - start_sample_index) >
(32768+1))
num_samples = 32768-start_sample_index;

slope = (double)num_samples/(double)W;
for(int i=0; i<H; i++)
{
float max = float.MinValue;
int start =
start_sample_index+(int)Math.Floor(i*slope);
int finish =
start_sample_index+(int)Math.Floor((i+1)*slope);
if (start == finish)
{
max = a[start];
}
else
for(int j=start; j<finish; j++)
max = Math.Max(max, a[j]);

max = max + display_cal[20] + gain_correction +
att_correction;

if(max > display_max_y)
{
display_max_y = max;
display_max_x = i;
}

//data =
-(int)(Math.Floor(max*H/yRange));
data =max;
}


/**************************************************************************/
BitmapData bitmapData = waterfall_bmp.LockBits(
new Rectangle(0, 0, waterfall_bmp.Width,
waterfall_bmp.Height),
ImageLockMode.ReadWrite,
waterfall_bmp.PixelFormat);

int pixel_size = 3;
byte* column = null;

// first scroll image
int total_size = bitmapData.Stride * bitmapData.Height; // find
buffer size
byte[] buffer = new byte[total_size]; // create
buffer
Marshal.Copy(bitmapData.Scan0, buffer, 0, total_size); //
copy bitmap to buffer
Marshal.Copy( buffer, 0,
new
IntPtr((int)bitmapData.Scan0+bitmapData.Stride), //
slide memory and copy back
total_size - bitmapData.Stride);
buffer = null;

row = (byte *)bitmapData.Scan0;

/***********************************************************************************/

// draw new data
for(int i=0; i<W; i++) // for each pixel in the new line
{
int R, G, B;
if(data <= waterfall_low_threshold) // if
less than low threshold use low color
{
R = waterfall_low_color.R;
G = waterfall_low_color.G;
B = waterfall_low_color.B;
}
else if(data >= waterfall_high_threshold) //
if more than high threshold use high color
{
R = waterfall_high_color.R;
G = waterfall_high_color.G;
B = waterfall_high_color.B;
}
else // use a color between high and low
{
float percent = (data -
waterfall_low_threshold)/(waterfall_high_threshold -
waterfall_low_threshold);
if(percent <= 0.5) // use a gradient between low and
mid colors
{
percent *= 2;

R = (int)((1-percent)*waterfall_low_color.R +
percent*waterfall_mid_color.R);
G = (int)((1-percent)*waterfall_low_color.G +
percent*waterfall_mid_color.G);
B = (int)((1-percent)*waterfall_low_color.B +
percent*waterfall_mid_color.B);
}
else // use a gradient between mid and high colors
{

percent = (float)(percent-0.5)*2;

R = (int)((1-percent)*waterfall_mid_color.R +
percent*waterfall_high_color.R);
G = (int)((1-percent)*waterfall_mid_color.G +
percent*waterfall_high_color.G);
B = (int)((1-percent)*waterfall_mid_color.B +
percent*waterfall_high_color.B);
}
}

// set pixel color
row[i*pixel_size + 0] = (byte)B; // set color in
memory
row[i*pixel_size + 1] = (byte)G;
row[i*pixel_size + 2] = (byte)R;
}



waterfall_bmp.UnlockBits(bitmapData);
g.DrawImageUnscaled(waterfall_bmp, 0, 16); // draw the image
on the background

waterfall_counter++;


// draw long cursor
if(long_crosshair)
{
g.DrawLine(new Pen(grid_text_color), display_cursor_x,
0, display_cursor_x, H);
g.DrawLine(new Pen(grid_text_color), 0,
display_cursor_y, W, display_cursor_y);
}
if(display_high_swr)
g.DrawString( "High SWR", new
Font("Arial", 14, FontStyle.Bold),
new SolidBrush(Color.Red), 245, 20);
}


*-----------------------*
Posted at:
www.GroupSrv.com
*-----------------------*
 
S

Sherif ElMetainy

Hello

You can use the following method to rotate an image by 90 degrees
(clockwise) and return the rotated image.

System.Drawing.Image Rotate90(System.Drawing.Image img)
{
System.Drawing.Image img2 = new System.Drawing.Bitmap(img.Height,
img.Width);
using(System.Drawing.Graphics g =
System.Drawing.Graphics.FromImage(img2))
{
g.RotateTransform(90, System.Drawing.Drawing2D.MatrixOrder.Append);
g.TranslateTransform(img2.Width, 0,
System.Drawing.Drawing2D.MatrixOrder.Append);
g.DrawImageUnscaled(img, 0, 0);
}
return img2;
}

Best regards,
Sherif

asognoth said:
Hi...

Does anybody have a clue how to solve this problem?

the task is to change the following method in that manner that it
draws the (calculated) image form left to right instead of from top
to bottom. The image is actually a waterfall model of sound data.

I tried desperatly, but I don't see how to swap the x and y
coordinates.
Anybody got a hint?

Here is the method:

unsafe private void DrawWaterfall(ref Graphics g, int W, int
H)
{
bool MOX = false;
float[] data = new float[W]; // array of points to
display
double slope = 0.0; // samples to process per pixel
int num_samples = 0; // number of samples to process
int start_sample_index = 0; // index to begin looking at samples
int low = 0;
int high = 0;
display_max_y = Int32.MinValue;

if(!MOX)
{
low = DttSP.RXDisplayLow;
high = DttSP.RXDisplayHigh;
}
else
{
low = DttSP.TXDisplayLow;
high = DttSP.TXDisplayHigh;
}

int yRange = spectrum_grid_max - spectrum_grid_min;

float[] a = new float[32768];

my_con.dsp_display_mutex.WaitOne();
fixed(float* ptr =
&a[0])DttSP.GetSpectrum(ptr);
my_con.dsp_display_mutex.ReleaseMutex();

if(average_display)
{
if(average_buffer[0] == CLEAR_FLAG)
{
for(int i=0; i<32768; i++)
average_buffer = a;
}
else
{
for(int i=0; i<32768; i++)
average_buffer = a =
(float)(a*average_mult_samp
+average_buffer*average_mult_avg);
}
}

num_samples = (high - low);

start_sample_index = (32768>>1)
+(int)((low * 32768) / DttSP.SampleRate);
num_samples = (int)((high - low) * 32768 /
DttSP.SampleRate);

if (start_sample_index < 0)
start_sample_index = 0;
if ((num_samples - start_sample_index) >
(32768+1))
num_samples = 32768-start_sample_index;

slope = (double)num_samples/(double)W;
for(int i=0; i<H; i++)
{
float max = float.MinValue;
int start =
start_sample_index+(int)Math.Floor(i*slope);
int finish =
start_sample_index+(int)Math.Floor((i+1)*slope);
if (start == finish)
{
max = a[start];
}
else
for(int j=start; j<finish; j++)
max = Math.Max(max, a[j]);

max = max + display_cal[20] + gain_correction +
att_correction;

if(max > display_max_y)
{
display_max_y = max;
display_max_x = i;
}

//data =
-(int)(Math.Floor(max*H/yRange));
data =max;
}


/**************************************************************************/
BitmapData bitmapData = waterfall_bmp.LockBits(
new Rectangle(0, 0, waterfall_bmp.Width,
waterfall_bmp.Height),
ImageLockMode.ReadWrite,
waterfall_bmp.PixelFormat);

int pixel_size = 3;
byte* column = null;

// first scroll image
int total_size = bitmapData.Stride * bitmapData.Height; // find
buffer size
byte[] buffer = new byte[total_size]; // create
buffer
Marshal.Copy(bitmapData.Scan0, buffer, 0, total_size); //
copy bitmap to buffer
Marshal.Copy( buffer, 0,
new
IntPtr((int)bitmapData.Scan0+bitmapData.Stride), //
slide memory and copy back
total_size - bitmapData.Stride);
buffer = null;

row = (byte *)bitmapData.Scan0;

/***************************************************************************
********/

// draw new data
for(int i=0; i<W; i++) // for each pixel in the new line
{
int R, G, B;
if(data <= waterfall_low_threshold) // if
less than low threshold use low color
{
R = waterfall_low_color.R;
G = waterfall_low_color.G;
B = waterfall_low_color.B;
}
else if(data >= waterfall_high_threshold) //
if more than high threshold use high color
{
R = waterfall_high_color.R;
G = waterfall_high_color.G;
B = waterfall_high_color.B;
}
else // use a color between high and low
{
float percent = (data -
waterfall_low_threshold)/(waterfall_high_threshold -
waterfall_low_threshold);
if(percent <= 0.5) // use a gradient between low and
mid colors
{
percent *= 2;

R = (int)((1-percent)*waterfall_low_color.R +
percent*waterfall_mid_color.R);
G = (int)((1-percent)*waterfall_low_color.G +
percent*waterfall_mid_color.G);
B = (int)((1-percent)*waterfall_low_color.B +
percent*waterfall_mid_color.B);
}
else // use a gradient between mid and high colors
{

percent = (float)(percent-0.5)*2;

R = (int)((1-percent)*waterfall_mid_color.R +
percent*waterfall_high_color.R);
G = (int)((1-percent)*waterfall_mid_color.G +
percent*waterfall_high_color.G);
B = (int)((1-percent)*waterfall_mid_color.B +
percent*waterfall_high_color.B);
}
}

// set pixel color
row[i*pixel_size + 0] = (byte)B; // set color in
memory
row[i*pixel_size + 1] = (byte)G;
row[i*pixel_size + 2] = (byte)R;
}



waterfall_bmp.UnlockBits(bitmapData);
g.DrawImageUnscaled(waterfall_bmp, 0, 16); // draw the image
on the background

waterfall_counter++;


// draw long cursor
if(long_crosshair)
{
g.DrawLine(new Pen(grid_text_color), display_cursor_x,
0, display_cursor_x, H);
g.DrawLine(new Pen(grid_text_color), 0,
display_cursor_y, W, display_cursor_y);
}
if(display_high_swr)
g.DrawString( "High SWR", new
Font("Arial", 14, FontStyle.Bold),
new SolidBrush(Color.Red), 245, 20);
}


*-----------------------*
Posted at:
www.GroupSrv.com
*-----------------------*
 
M

Mick Doherty

Bitmap has a RotateFlip method.

Bitmap Rotate90(Bitmap someImage)
{
Bitmap bmp = new Bitmap(someImage);
bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
return bmp;
}

--
Mick Doherty
http://dotnetrix.co.uk/nothing.html


Sherif ElMetainy said:
Hello

You can use the following method to rotate an image by 90 degrees
(clockwise) and return the rotated image.

System.Drawing.Image Rotate90(System.Drawing.Image img)
{
System.Drawing.Image img2 = new System.Drawing.Bitmap(img.Height,
img.Width);
using(System.Drawing.Graphics g =
System.Drawing.Graphics.FromImage(img2))
{
g.RotateTransform(90, System.Drawing.Drawing2D.MatrixOrder.Append);
g.TranslateTransform(img2.Width, 0,
System.Drawing.Drawing2D.MatrixOrder.Append);
g.DrawImageUnscaled(img, 0, 0);
}
return img2;
}

Best regards,
Sherif

asognoth said:
Hi...

Does anybody have a clue how to solve this problem?

the task is to change the following method in that manner that it
draws the (calculated) image form left to right instead of from top
to bottom. The image is actually a waterfall model of sound data.

I tried desperatly, but I don't see how to swap the x and y
coordinates.
Anybody got a hint?

Here is the method:

unsafe private void DrawWaterfall(ref Graphics g, int W, int
H)
{
bool MOX = false;
float[] data = new float[W]; // array of points to
display
double slope = 0.0; // samples to process per pixel
int num_samples = 0; // number of samples to process
int start_sample_index = 0; // index to begin looking at samples
int low = 0;
int high = 0;
display_max_y = Int32.MinValue;

if(!MOX)
{
low = DttSP.RXDisplayLow;
high = DttSP.RXDisplayHigh;
}
else
{
low = DttSP.TXDisplayLow;
high = DttSP.TXDisplayHigh;
}

int yRange = spectrum_grid_max - spectrum_grid_min;

float[] a = new float[32768];

my_con.dsp_display_mutex.WaitOne();
fixed(float* ptr =
&a[0])DttSP.GetSpectrum(ptr);
my_con.dsp_display_mutex.ReleaseMutex();

if(average_display)
{
if(average_buffer[0] == CLEAR_FLAG)
{
for(int i=0; i<32768; i++)
average_buffer = a;
}
else
{
for(int i=0; i<32768; i++)
average_buffer = a =
(float)(a*average_mult_samp
+average_buffer*average_mult_avg);
}
}

num_samples = (high - low);

start_sample_index = (32768>>1)
+(int)((low * 32768) / DttSP.SampleRate);
num_samples = (int)((high - low) * 32768 /
DttSP.SampleRate);

if (start_sample_index < 0)
start_sample_index = 0;
if ((num_samples - start_sample_index) >
(32768+1))
num_samples = 32768-start_sample_index;

slope = (double)num_samples/(double)W;
for(int i=0; i<H; i++)
{
float max = float.MinValue;
int start =
start_sample_index+(int)Math.Floor(i*slope);
int finish =
start_sample_index+(int)Math.Floor((i+1)*slope);
if (start == finish)
{
max = a[start];
}
else
for(int j=start; j<finish; j++)
max = Math.Max(max, a[j]);

max = max + display_cal[20] + gain_correction +
att_correction;

if(max > display_max_y)
{
display_max_y = max;
display_max_x = i;
}

//data =
-(int)(Math.Floor(max*H/yRange));
data =max;
}


/**************************************************************************/
BitmapData bitmapData = waterfall_bmp.LockBits(
new Rectangle(0, 0, waterfall_bmp.Width,
waterfall_bmp.Height),
ImageLockMode.ReadWrite,
waterfall_bmp.PixelFormat);

int pixel_size = 3;
byte* column = null;

// first scroll image
int total_size = bitmapData.Stride * bitmapData.Height; // find
buffer size
byte[] buffer = new byte[total_size]; // create
buffer
Marshal.Copy(bitmapData.Scan0, buffer, 0, total_size); //
copy bitmap to buffer
Marshal.Copy( buffer, 0,
new
IntPtr((int)bitmapData.Scan0+bitmapData.Stride), //
slide memory and copy back
total_size - bitmapData.Stride);
buffer = null;

row = (byte *)bitmapData.Scan0;

/***************************************************************************
********/

// draw new data
for(int i=0; i<W; i++) // for each pixel in the new line
{
int R, G, B;
if(data <= waterfall_low_threshold) // if
less than low threshold use low color
{
R = waterfall_low_color.R;
G = waterfall_low_color.G;
B = waterfall_low_color.B;
}
else if(data >= waterfall_high_threshold) //
if more than high threshold use high color
{
R = waterfall_high_color.R;
G = waterfall_high_color.G;
B = waterfall_high_color.B;
}
else // use a color between high and low
{
float percent = (data -
waterfall_low_threshold)/(waterfall_high_threshold -
waterfall_low_threshold);
if(percent <= 0.5) // use a gradient between low and
mid colors
{
percent *= 2;

R = (int)((1-percent)*waterfall_low_color.R +
percent*waterfall_mid_color.R);
G = (int)((1-percent)*waterfall_low_color.G +
percent*waterfall_mid_color.G);
B = (int)((1-percent)*waterfall_low_color.B +
percent*waterfall_mid_color.B);
}
else // use a gradient between mid and high colors
{

percent = (float)(percent-0.5)*2;

R = (int)((1-percent)*waterfall_mid_color.R +
percent*waterfall_high_color.R);
G = (int)((1-percent)*waterfall_mid_color.G +
percent*waterfall_high_color.G);
B = (int)((1-percent)*waterfall_mid_color.B +
percent*waterfall_high_color.B);
}
}

// set pixel color
row[i*pixel_size + 0] = (byte)B; // set color in
memory
row[i*pixel_size + 1] = (byte)G;
row[i*pixel_size + 2] = (byte)R;
}



waterfall_bmp.UnlockBits(bitmapData);
g.DrawImageUnscaled(waterfall_bmp, 0, 16); // draw the image
on the background

waterfall_counter++;


// draw long cursor
if(long_crosshair)
{
g.DrawLine(new Pen(grid_text_color), display_cursor_x,
0, display_cursor_x, H);
g.DrawLine(new Pen(grid_text_color), 0,
display_cursor_y, W, display_cursor_y);
}
if(display_high_swr)
g.DrawString( "High SWR", new
Font("Arial", 14, FontStyle.Bold),
new SolidBrush(Color.Red), 245, 20);
}


*-----------------------*
Posted at:
www.GroupSrv.com
*-----------------------*

 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top