I'm working emgucv project, But I have problem.
I want as a result of this image
I accept the four input coordinates and want to Perspective with a new image.
But my code is impossible...
This is my code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Image<Bgr, byte> image = new Image<Bgr, byte>(#"C:\Users4.jpg");
Bitmap bitImage;
ImageConverter im = new ImageConverter();
int w, h;
int count = 4;
int a = 0;
HomographyMatrix homography;
PointF[] spoint = new PointF[4];
PointF[] dpoint = new PointF[4];
public Form1()
{
InitializeComponent();
}
private void Form1_Shown(object sender, EventArgs e)
{
bitImage = new Bitmap(#"C:\Users4.jpg");
w = bitImage.Width;
h = bitImage.Height;
this.Size = new System.Drawing.Size(w, h);
ibCanvas.BackgroundImage = bitImage;
}
/*
When taking the mouse coordinates being the X and Y axes to the coordinates stored in the Point array.
*/
private void ibCanvas_MouseDown(object sender, MouseEventArgs e)
{
if (count != 0)
{
spoint[a] = new PointF(e.X, e.Y);
a++;
count -= 1;
}
if (count == 0)
{
count = 4;
a = 0;
PointF[] pts1 = new PointF[4];
PointF[] pts2 = new PointF[4];
label1.Text = spoint[0].ToString();
label2.Text = spoint[1].ToString();
label3.Text = spoint[2].ToString();
label4.Text = spoint[3].ToString();
double w1 = Math.Sqrt(Math.Pow(spoint[3].X - spoint[0].X, 2)
+ Math.Pow(spoint[3].X - spoint[0].X, 2));
double w2 = Math.Sqrt(Math.Pow(spoint[2].X - spoint[1].X, 2)
+ Math.Pow(spoint[2].X - spoint[1].X, 2));
double h1 = Math.Sqrt(Math.Pow(spoint[3].Y - spoint[2].Y, 2)
+ Math.Pow(spoint[3].Y - spoint[2].Y, 2));
double h2 = Math.Sqrt(Math.Pow(spoint[0].Y - spoint[1].Y, 2)
+ Math.Pow(spoint[0].Y - spoint[1].Y, 2));
double maxWidth = (w1 < w2) ? w1 : w2;
double maxHeight = (h1 < h2) ? h1 : h2;
dpoint[0].X = 0;
dpoint[0].Y = 0;
dpoint[1].X = 0;
dpoint[1].Y = ((float)maxHeight-1);
dpoint[2].X = ((float)maxWidth - 1); ;
dpoint[2].Y = ((float)maxHeight - 1); ;
dpoint[3].X = ((float)maxWidth - 1); ;
dpoint[3].Y = 0;
homography = CameraCalibration.GetPerspectiveTransform(spoint, dpoint);
Image<Bgr, byte> newImage = image.WarpPerspective(homography, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, Emgu.CV.CvEnum.WARP.CV_WARP_DEFAULT, new Bgr(0, 0, 0));
CvInvoke.cvShowImage("new Image", newImage);
}
}
}
}
I want really solve this problem
Please Help me!
Related
I have list XY points are including 16000 points, I deployed it to 2 chart type waveform chart and arc graph. I used the class name is VerticalLineAnnotation to design the vertical line on waveform chart and add series chart type line on arc graph to reflect any the last X point of the veritcal line on arc graph. When move the vertical line to left-right, it work very well but when I leave mouse out the line, the charts (waveforma and arc graph) are redraw and take to long time. How can I prevent it (redraw event) or speed up?.
This is source code
ChartArea CA;
Series S1;
VerticalLineAnnotation VA;
double degree = 0;
int test = 0;
Dictionary<int, PointXY> xyMap = new Dictionary<int, PointXY>();
private void DrawGraph(DataTable dtExcel)
{
Series series1 = new Series("Series2");
series1.ChartArea = "ChartArea1";
series1.ChartType = SeriesChartType.Spline;
series1.Color = Color.White;
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = 1000;
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = 4500;
chart1.ChartAreas["ChartArea1"].AxisY.Interval = 500;
chart1.ChartAreas["ChartArea1"].AxisX.Minimum = 0;
chart1.ChartAreas["ChartArea1"].AxisX.Maximum = 16000;
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 1000;
Series series2 = new Series("Series2");
series2.ChartArea = "ChartArea1";
series2.ChartType = SeriesChartType.Spline;
series2.Color = Color.White;
chart2.ChartAreas["ChartArea1"].AxisY.Minimum = -100;
chart2.ChartAreas["ChartArea1"].AxisY.Maximum = 100;
chart2.ChartAreas["ChartArea1"].AxisY.Interval = 10;
chart2.ChartAreas["ChartArea1"].AxisX.Minimum = -100;
chart2.ChartAreas["ChartArea1"].AxisX.Maximum = 100;
chart2.ChartAreas["ChartArea1"].AxisX.Interval = 10;
foreach (DataRow item in dtExcel.Rows)
{
series1.Points.AddXY(int.Parse(item[0].ToString()), item[1].ToString());
CaculatePointXY(item, series2);
}
chart1.Series.Add(series1);
chart1.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineColor = Color.Green;
chart1.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineColor = Color.Green;
chart1.ChartAreas["ChartArea1"].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont;
chart2.Series.Add(series2);
chart2.ChartAreas["ChartArea1"].AxisX.MajorGrid.LineColor = Color.Green;
chart2.ChartAreas["ChartArea1"].AxisY.MajorGrid.LineColor = Color.Green;
chart2.ChartAreas["ChartArea1"].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont;
//Draw vertical line
CA = chart1.ChartAreas["ChartArea1"];
VA = new VerticalLineAnnotation();
VA.AxisX = CA.AxisX;
VA.AllowMoving = true;
VA.IsInfinitive = true;
VA.ClipToChartArea = CA.Name;
VA.Name = "myLine";
VA.LineColor = Color.Red;
VA.LineWidth = 2; // use your numbers!
VA.X = 8000;
chart1.Annotations.Add(VA);
chart2.Series.Add("Line");
chart2.Series["Line"].Points.Add(new DataPoint(0, 0));
chart2.Series["Line"].Color = Color.Red;
chart2.Series["Line"].BorderWidth = 2;
chart2.Series["Line"].Points.Add(new DataPoint(0, 100));
chart2.Series["Line"].ChartType = SeriesChartType.Line;
}
private void CaculatePointXY(DataRow item, Series series2)
{
double distance = (int.Parse(item[1].ToString()) - 819) * 0.0030525;
distance += 95;
double x = distance * Math.Cos((degree * Math.PI / 180));
double y = distance * Math.Sin((degree * Math.PI / 180));
series2.Points.AddXY(x, y);
xyMap.Add(int.Parse(item[0].ToString()), new PointXY()
{
X = x,
Y = y
});
degree += 0.0225;
}
private void chart1_Customize(object sender, EventArgs e)
{
foreach (var label in chart1.ChartAreas[0].AxisY.CustomLabels)
{
label.Text = ((int)double.Parse(label.Text) / 100).ToString();
}
foreach (var label in chart1.ChartAreas[0].AxisX.CustomLabels)
{
label.Text = ((int)double.Parse(label.Text) / 100).ToString();
}
}
private void chart1_MouseDoubleClick(object sender, MouseEventArgs e)
{
var xVal = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X);
var yVal = chart1.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);
ZoomWaveFormGraph(xVal, yVal);
}
private void ZoomWaveFormGraph(double xVal, double yVal)
{
ZoomArcGraph((int)xVal);
var YMin = Math.Round(yVal - 1000, 0);
var YMax = Math.Round(yVal + 1000, 0);
chart1.ChartAreas["ChartArea1"].AxisY.Minimum = YMin;
chart1.ChartAreas["ChartArea1"].AxisY.Maximum = YMax;
chart1.ChartAreas["ChartArea1"].AxisY.Interval = 100;
var XMin = Math.Round(xVal - 1000, 0);
var XMax = Math.Round(xVal + 1000, 0);
chart1.ChartAreas["ChartArea1"].AxisX.Minimum = XMin;
chart1.ChartAreas["ChartArea1"].AxisX.Maximum = XMax;
chart1.ChartAreas["ChartArea1"].AxisX.Interval = 200;
}
private void ZoomArcGraph(double xVal)
{
int a = (int)xVal;
var b = xyMap[a];
chart2.ChartAreas["ChartArea1"].AxisY.Minimum = Math.Round(b.Y - 20, 0);
chart2.ChartAreas["ChartArea1"].AxisY.Maximum = Math.Round(b.Y + 20, 0);
chart2.ChartAreas["ChartArea1"].AxisY.Interval = 2;
chart2.ChartAreas["ChartArea1"].AxisX.Minimum = Math.Round(b.X - 20, 0);
chart2.ChartAreas["ChartArea1"].AxisX.Maximum = Math.Round(b.X + 20, 0);
chart2.ChartAreas["ChartArea1"].AxisX.Interval = 2;
}
private double RadianToDegree(double angle)
{
return angle * (180.0 / Math.PI);
}
private void chart1_AnnotationPositionChanging(object sender, AnnotationPositionChangingEventArgs e)
{
test = (int)Math.Round(e.NewLocationX, 0);
Console.WriteLine("X : " + e.NewLocationX.ToString());
}
private void chart1_AnnotationPositionChanged(object sender, EventArgs e)
{
var a = xyMap[test];
chart2.Series["Line"].Points.ElementAt(1).SetValueXY(a.X, a.Y);
chart2.Refresh();
}
What command should I use to increase interval between two points? On the graph.
I guess chart. shoul help me but what exactly?
public static void ShowHeatmap(string title, double[,] heat, int xMin, int yMin)
{
var chart = new ZedGraphControl()
{
Dock = DockStyle.Fill
};
var maxHeat = heat.Cast<double>().Max();
chart.GraphPane.Title.Text = title;
chart.GraphPane.YAxis.Title.Text = "Дни";
chart.GraphPane.YAxis.Title.Text = "Месяцы";
var maxSize = Math.Max(heat.GetLength(0), Math.Pow(heat.GetLength(1),2));
for (int x = 0; x < heat.GetLength(0); x++)
for (int y = 0; y < heat.GetLength(1); y++)
{
var value = heat[x, y];
if (value > 1000) throw new ArgumentException("too large heat value " + value);
var color = Color.FromArgb(255, 200, (int)(255 * value / maxHeat), 0);
var lineItem = chart.GraphPane.AddCurve("", new double[] { x + xMin }, new double[] { y + yMin }, color);
lineItem.Symbol.Type = SymbolType.Circle;
lineItem.Symbol.Fill = new Fill(color);
lineItem.Symbol.Size = (float)(6000 * value / maxHeat / maxSize);
}
chart.GraphPane.YAxis.Scale.MaxAuto = true;
chart.GraphPane.YAxis.Scale.MinAuto = true;
chart.AxisChange();
var form = new Form();
form.Text = title;
form.Size = new Size(1920, 1080);
form.Controls.Add(chart);
form.ShowDialog();
When my windows form loads the tool strip menu item bar is there but the items inside it are not shown until I hover over them or press alt.
Also, my colordialog box wont open until after I click the change color icon in my menu and then press Alt.
I've had a look through the properties to make sure there is no hide property on or something but I can't seem to find anything.
I've posted some links below to show you what's happening.
When it opens up: http://gyazo.com/c1f4fa4d27e3f54a65b1f8a3da6cd0da
When I press alt or hover over menu: http://gyazo.com/c86c5dfb723647c025f89a0c14da6766
Not sure what code to put in.
Changing color bit:
private void changeColourToolStripMenuItem_Click(object sender, EventArgs e)
{
DialogResult result = colorDialog1.ShowDialog();
}
I just dragged the elements on from the toolbox.
All Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Assignment
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
init();
start();
this.DoubleBuffered = true;
}
//code to convert HSB to RGB from HSB.cs. All your code so i made it take up less space.
public struct HSBColor
{
float h;
float s;
float b;
int a;
public HSBColor(float h, float s, float b) { this.a = 0xff; this.h = Math.Min(Math.Max(h, 0), 255); this.s = Math.Min(Math.Max(s, 0), 255); this.b = Math.Min(Math.Max(b, 0), 255); }
public HSBColor(int a, float h, float s, float b) { this.a = a; this.h = Math.Min(Math.Max(h, 0), 255); this.s = Math.Min(Math.Max(s, 0), 255); this.b = Math.Min(Math.Max(b, 0), 255); }
public float H { get { return h; } }
public float S { get { return s; } }
public float B { get { return b; } }
public int A { get { return a; } }
public Color Color { get { return FromHSB(this); } }
public static Color FromHSB(HSBColor hsbColor)
{
float r = hsbColor.b;
float g = hsbColor.b;
float b = hsbColor.b;
if (hsbColor.s != 0)
{
float max = hsbColor.b; float dif = hsbColor.b * hsbColor.s / 255f; float min = hsbColor.b - dif; float h = hsbColor.h * 360f / 255f;
if (h < 60f) { r = max; g = h * dif / 60f + min; b = min; }
else if (h < 120f) { r = -(h - 120f) * dif / 60f + min; g = max; b = min; }
else if (h < 180f) { r = min; g = max; b = (h - 120f) * dif / 60f + min; }
else if (h < 240f) { r = min; g = -(h - 240f) * dif / 60f + min; b = max; }
else if (h < 300f) { r = (h - 240f) * dif / 60f + min; g = min; b = max; }
else if (h <= 360f) { r = max; g = min; b = -(h - 360f) * dif / 60 + min; }
else { r = 0; g = 0; b = 0; }
}
return Color.FromArgb(hsbColor.a, (int)Math.Round(Math.Min(Math.Max(r, 0), 255)), (int)Math.Round(Math.Min(Math.Max(g, 0), 255)), (int)Math.Round(Math.Min(Math.Max(b, 0), 255)));
}
}
private const int MAX = 256; // max iterations
private const double SX = -2.025; // start value real
private const double SY = -1.125; // start value imaginary
private const double EX = 0.6; // end value real
private const double EY = 1.125; // end value imaginary
private static int x1, y1, xs, ys, xe, ye;
private static double xstart, ystart, xende, yende, xzoom, yzoom;
private static float xy;
private int c = 0;
//private Image picture; Taken out, not needed
// create rectangle variable JGB
Rectangle rec;
private Graphics g1;
//private Cursor c1, c2; Taken out, not needed
private System.Drawing.Bitmap bitmap;
public void init()
{
//setSize(640, 480); changed this code to JGB:
this.Size = new Size(640, 480);
// Taken all lines out below. Not needed.
/*finished = false;
addMouseListener(this);
addMouseMotionListener(this);
c1 = new Cursor(Cursor.WAIT_CURSOR);
c2 = new Cursor(Cursor.CROSSHAIR_CURSOR); */
x1 = 640;
y1 = 480;
xy = (float)x1 / (float)y1;
//picture = createImage(x1, y1); Taken out and replaced with JGB:
bitmap = new Bitmap(x1, y1);
//g1 = picture.getGraphics(); changed to get my bitmap
g1 = Graphics.FromImage(bitmap);
//finished = true; Finished variable deleted so not needed
}
//Code below didnt appear to do anything so i deleted it
/*public void destroy() // delete all instances
{
if (finished)
{
removeMouseListener(this);
removeMouseMotionListener(this);
picture = null;
g1 = null;
c1 = null;
c2 = null;
System.gc(); // garbage collection
}
} */
public void start()
{
//action = false;
//rectangle = false;
initvalues();
// added dialog box for instance loading and save varaibles needed for position and zoom to text file
DialogResult dialog = MessageBox.Show("Would You Like to Load Your Last Instance?", "Load Instance?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (dialog == DialogResult.Yes)
{
string[] lines = System.IO.File.ReadAllLines(#"C:\Users\Public\Writelines.txt");
xzoom = System.Convert.ToDouble(lines[0]);
yzoom = System.Convert.ToDouble(lines[1]);
xstart = System.Convert.ToDouble(lines[2]);
ystart = System.Convert.ToDouble(lines[3]);
}
else
{
xzoom = (xende - xstart) / (double)x1;
yzoom = (yende - ystart) / (double)y1;
}
mandelbrot();
}
public void stop()
{
}
/*public void paint(Graphics g, PaintEventArgs e)
{
update(g);
}
public void update(Graphics g)
{
//g.DrawImage(picture, 0, 0);
}*/
private void mandelbrot()
{
int x, y;
float h, b, alt = 0.0f;
Color color;
Pen pen = new Pen(Color.Black);
for (x = 0; x < x1; x += 2)
for (y = 0; y < y1; y++)
{
h = pointcolour(xstart + xzoom * (double)x, ystart + yzoom * (double)y, c);
if (h != alt)
{
b = 1.0f - h * h;
color = HSBColor.FromHSB(new HSBColor(h * 255, 0.8f * 255, b * 255));
pen = new Pen(color);
alt = h;
}
g1.DrawLine(pen, x, y, x + 1, y);
}
}
private float pointcolour(double xwert, double ywert, int j)
{
double r = 0.0, i = 0.0, m = 0.0;
// int j = 0;
while ((j < MAX) && (m < 4.0))
{
j++;
m = r * r - i * i;
i = 2.0 * r * i + ywert;
r = m + xwert;
}
return (float)j / (float)MAX;
}
private void initvalues()
{
xstart = SX;
ystart = SY;
xende = EX;
yende = EY;
if ((float)((xende - xstart) / (yende - ystart)) != xy)
xstart = xende - (yende - ystart) * (double)xy;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g1 = e.Graphics;
g1.DrawImage(bitmap, 0, 0, x1, y1);
using (Pen pen = new Pen(Color.White, 2))
{
e.Graphics.DrawRectangle(pen, rec);
}
Invalidate();
}
//added load method
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
xe = e.X;
ye = e.Y;
if (xs < xe)
{
if (ys < ye) rec = new Rectangle(xs, ys, (xe - xs), (ye - ys));
else rec = new Rectangle(xs, ye, (xe - xs), (ys - ye));
}
else
{
if (ys < ye) rec = new Rectangle(xe, ys, (xs - xe), (ye - ys));
else rec = new Rectangle(xe, ye, (xs - xe), (ys - ye));
}
this.Invalidate();
}
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// e.consume();
xs = e.X;
ys = e.Y; // starting point y
this.Invalidate();
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
rec = new Rectangle(0, 0, 0, 0);
if (e.Button == MouseButtons.Left)
{
int z, w;
//e.consume();
//xe = e.X;
//ye = e.Y;
if (xs > xe)
{
z = xs;
xs = xe;
xe = z;
}
if (ys > ye)
{
z = ys;
ys = ye;
ye = z;
}
w = (xe - xs);
z = (ye - ys);
if ((w < 2) && (z < 2)) initvalues();
else
{
if (((float)w > (float)z * xy)) ye = (int)((float)ys + (float)w / xy);
else xe = (int)((float)xs + (float)z * xy);
xende = xstart + xzoom * (double)xe;
yende = ystart + yzoom * (double)ye;
xstart += xzoom * (double)xs;
ystart += yzoom * (double)ys;
}
xzoom = (xende - xstart) / (double)x1;
yzoom = (yende - ystart) / (double)y1;
mandelbrot();
string stringxzoom = xzoom.ToString();
string stringyzoom = yzoom.ToString();
string stringystart = ystart.ToString();
string stringxstart = xstart.ToString();
string[] lines = { stringxzoom, stringyzoom, stringxstart, stringystart };
System.IO.File.WriteAllLines(#"C:\Users\Public\Writelines.txt", lines);
this.Invalidate();
//Repaint();
}
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
dialog.InitialDirectory =System.Environment.GetFolderPath(Environment.SpecialFolder.Personal);
dialog.Title = "Save Image";
dialog.FileName = "";
dialog.Filter = "JPEG|*.jpg";
dialog.ShowDialog();
}
private void restartToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Restart();
}
private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void changeColourToolStripMenuItem_Click(object sender, EventArgs e)
{
colorDialog1.ShowDialog();
}
private void menuToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
}
}
Ok so after hours of trying to figure this out i found the solution. A random invalidate was messing it up.
Thanks anyway to #Sjips for the fast help.
I want to know the error in the following code.I want to draw the values of array that contains wave file samples.in the form i put panel and inside it picturebox.
private void button1_Click(object sender, EventArgs e)
{
string ss = "test.wav";
double[] xxwav = prepare(ss);
int xmin = 300; int ymin = 250; int xmax = 1024; int ymax = 450;
int xpmin = 0; int xpmax = xxwav.Length; int ypmin = 32767; int ypmax = -32768;
double a = (double)((xmax - xmin)) /(double) (xpmax - xpmin);
double b = (double)(xpmin - (a * xmin));
double c = (double)((ymax - ymin) /(double) (ypmax - ypmin));
double d = (double)(ypmin - (c * ymin));
double xp1,yp1,xp2,yp2;
Pen redPen = new Pen(Color.Red, 1);
Bitmap bmp = new Bitmap(40000, 500);
Graphics g = Graphics.FromImage(bmp);
PointF p1;
PointF p2;
for (int i = 1; i < xxwav.Length; i++)
{
xp1 = a * (i-1) + b;
yp1 = c * xxwav[i-1] + d;
xp2=a * i + b;
yp2=c * xxwav[i] + d;
p1 =new PointF ((float)xp1,(float)yp1);
p2 =new PointF ((float)xp2,(float)yp2);
g.DrawLine(redPen, p1, p2);
}
pictureBox1.Image = bmp;
MessageBox.Show("complete");
}
public static Double[] prepare(String wavePath)
{
Double[] data;
byte[] wave;
byte[] sR = new byte[4];
System.IO.FileStream WaveFile = System.IO.File.OpenRead(wavePath);
wave = new byte[WaveFile.Length];
data = new Double[(wave.Length - 44) / 4];//shifting the headers out of the PCM data;
WaveFile.Read(wave, 0, Convert.ToInt32(WaveFile.Length));//read the wave file into the wave variable
/***********Converting and PCM accounting***************/
for (int i = 0; i < data.Length; i++)
{
data[i] = BitConverter.ToInt16(wave, i * 2) / 32768.0;
}
//65536.0.0=2^n, n=bits per sample;
return data;
}
Your code worked for me only after I fiddled with your transformations and scaling parameters.
I have replaced your code with the scaling and transformation methods available in the System.Drawing namespace. This did gave me a view of one of my wav files. You only have to replace the private void button1_Click(object sender, EventArgs e) implementation.
var xxwav = prepare(wavFile);
// determine max and min
var max = (from v in xxwav
select v).Max();
var min = (from v in xxwav
select v).Min();
// what is our Y-axis scale
var mid = (max - min);
Pen redPen = new Pen(Color.Red, 1);
Bitmap bmp = new Bitmap(this.pictureBox1.Size.Width, this.pictureBox1.Size.Height);
Graphics g = Graphics.FromImage(bmp);
// x / y position (y-axis to the middle)
g.TranslateTransform(
0
, this.pictureBox1.Size.Height / 2);
// scaling according to picturebox size
g.ScaleTransform(
(float)this.pictureBox1.Size.Width / (float)xxwav.Length
, (float)this.pictureBox1.Size.Height / ((float)mid));
//first point
var prev = new PointF(0, (float)xxwav[0]);
// iterate over next points
for (int i = 1; i < xxwav.Length; i++)
{
var next = new PointF((float) i , (float) xxwav[i] );
g.DrawLine(redPen, prev, next);
prev = next;
}
pictureBox1.Image = bmp;
I want to print one tall (long) image in many pages. So in every page, I take a suitable part from the image and I draw it in the page.
the problem is that I have got the image shrunk (its shape is compressed) in the page,so I added an scale that its value is 1500 .
I think that I can solve the problem if I knew the height of the page (e.Graphics) in pixels.
to convert Inches to Pixel, Do I have to multiply by (e.Graphics.DpiX = 600) or multiply by 96 .
void printdocument_PrintPage(object sender, PrintPageEventArgs e)
{
if (pageImage == null)
return;
e.Graphics.PageUnit = GraphicsUnit.Pixel;
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
float a = (e.MarginBounds.Width / 100) * e.Graphics.DpiX;
float b = ((e.MarginBounds.Height / 100) * e.Graphics.DpiY);
int scale = 1500;
scale = 0; //try to comment this
RectangleF srcRect = new RectangleF(0, startY, pageImage.Width, b - scale);
RectangleF destRect = new RectangleF(0, 0, a, b);
e.Graphics.DrawImage(pageImage, destRect, srcRect, GraphicsUnit.Pixel);
startY = Convert.ToInt32(startY + b - scale);
e.HasMorePages = (startY < pageImage.Height);
}
could you please make it works correctly.
you can download the source code from (here).
thanks in advanced.
I tried to complete your task.
Here you go. Hope it helps.
This method prints the image on several pages (or one if image is small).
private void printImage_Btn_Click(object sender, EventArgs e)
{
list = new List<Image>();
Graphics g = Graphics.FromImage(image_PctrBx.Image);
Brush redBrush = new SolidBrush(Color.Red);
Pen pen = new Pen(redBrush, 3);
decimal xdivider = image_PctrBx.Image.Width / 595m;
int xdiv = Convert.ToInt32(Math.Ceiling(xdivider));
decimal ydivider = image_PctrBx.Image.Height / 841m;
int ydiv = Convert.ToInt32(Math.Ceiling(ydivider));
/*int xdiv = image_PctrBx.Image.Width / 595; //This is the xsize in pt (A4)
int ydiv = image_PctrBx.Image.Height / 841; //This is the ysize in pt (A4)
// # 72 dots-per-inch - taken from Adobe Illustrator
if (xdiv >= 1 && ydiv >= 1)
{*/
for (int i = 0; i < xdiv; i++)
{
for (int y = 0; y < ydiv; y++)
{
Rectangle r;
try
{
r = new Rectangle(i * Convert.ToInt32(image_PctrBx.Image.Width / xdiv),
y * Convert.ToInt32(image_PctrBx.Image.Height / ydiv),
image_PctrBx.Image.Width / xdiv,
image_PctrBx.Image.Height / ydiv);
}
catch (Exception)
{
r = new Rectangle(i * Convert.ToInt32(image_PctrBx.Image.Width / xdiv),
y * Convert.ToInt32(image_PctrBx.Image.Height),
image_PctrBx.Image.Width / xdiv,
image_PctrBx.Image.Height);
}
g.DrawRectangle(pen, r);
list.Add(cropImage(image_PctrBx.Image, r));
}
}
g.Dispose();
image_PctrBx.Invalidate();
image_PctrBx.Image = list[0];
PrintDocument printDocument = new PrintDocument();
printDocument.PrintPage += PrintDocument_PrintPage;
PrintPreviewDialog previewDialog = new PrintPreviewDialog();
previewDialog.Document = printDocument;
pageIndex = 0;
previewDialog.ShowDialog();
// don't forget to detach the event handler when you are done
printDocument.PrintPage -= PrintDocument_PrintPage;
}
This method prints every picture in the List in the needed dimensions (A4 size):
private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
{
// Draw the image for the current page index
e.Graphics.DrawImageUnscaled(list[pageIndex],
e.PageBounds.X,
e.PageBounds.Y);
// increment page index
pageIndex++;
// indicate whether there are more pages or not
e.HasMorePages = (pageIndex < list.Count);
}
This method crops the image and returns every part of the image:
private static Image cropImage(Image img, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(img);
Bitmap bmpCrop = bmpImage.Clone(cropArea, System.Drawing.Imaging.PixelFormat.DontCare);
return (Image)(bmpCrop);
}
The Image gets loaded from the PictureBox, so make sure the image is loaded. (No exception handling yet).
internal string tempPath { get; set; }
private int pageIndex = 0;
internal List<Image> list { get; set; }
These variables are defined as global variables.
You can download a sample project here:
http://www.abouchleih.de/projects/PrintImage_multiplePages.zip // OLD Version
http://www.abouchleih.de/projects/PrintImage_multiplePages_v2.zip // NEW
I have Created a Class file for multiple page print a single large image.
Cls_PanelPrinting.Print Print =new Cls_PanelPrinting.Print(PnlContent/Image);
You have to Pass the panel or image.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Printing;
namespace Cls_PanelPrinting
{
public class Print
{
readonly PrintDocument printdoc1 = new PrintDocument();
readonly PrintPreviewDialog previewdlg = new PrintPreviewDialog();
public int page = 1;
internal string tempPath { get; set; }
private int pageIndex = 0;
internal List<Image> list { get; set; }
private int _Line = 0;
private readonly Panel panel_;
public Print(Panel pnl)
{
panel_ = pnl;
printdoc1.PrintPage += (printdoc1_PrintPage);
PrintDoc();
}
private void printdoc1_PrintPage(object sender, PrintPageEventArgs e)
{
Font myFont = new Font("Cambria", 10, FontStyle.Italic, GraphicsUnit.Point);
float lineHeight = myFont.GetHeight(e.Graphics) + 4;
float yLineTop = 1000;
int x = e.MarginBounds.Left;
int y = 25; //e.MarginBounds.Top;
e.Graphics.DrawImageUnscaled(list[pageIndex],
x,y);
pageIndex++;
e.HasMorePages = (pageIndex < list.Count);
e.Graphics.DrawString("Page No: " + pageIndex, myFont, Brushes.Black,
new PointF(e.MarginBounds.Right, yLineTop));
}
public void PrintDoc()
{
try
{
Panel grd = panel_;
Bitmap bmp = new Bitmap(grd.Width, grd.Height, grd.CreateGraphics());
grd.DrawToBitmap(bmp, new Rectangle(0, 0, grd.Width, grd.Height));
Image objImage = (Image)bmp;
Bitmap objBitmap = new Bitmap(objImage, new Size(700, objImage.Height));
Image PrintImage = (Image)objBitmap;
list = new List<Image>();
Graphics g = Graphics.FromImage(PrintImage);
Brush redBrush = new SolidBrush(Color.Red);
Pen pen = new Pen(redBrush, 3);
decimal xdivider = panel_.Width / 595m;
// int xdiv = Convert.ToInt32(Math.Ceiling(xdivider));
decimal ydivider = panel_.Height / 900m;
int ydiv = Convert.ToInt32(Math.Ceiling(ydivider));
int xdiv = panel_.Width / 595; //This is the xsize in pt (A4)
for (int i = 0; i < xdiv; i++)
{
for (int y = 0; y < ydiv; y++)
{
Rectangle r;
if (panel_.Height > 900)
{
try
{
if (list.Count > 0)
{
r = new Rectangle(0, (900 * list.Count), PrintImage.Width, PrintImage.Height - (900 * list.Count));
}
else
{
r = new Rectangle(0, 0, PrintImage.Width, 900);
}
list.Add(cropImage(PrintImage, r));
}
catch (Exception)
{
list.Add(PrintImage);
}
}
else { list.Add(PrintImage); }
}
}
g.Dispose();
PrintImage = list[0];
PrintDocument printDocument = new PrintDocument();
printDocument.PrintPage += printdoc1_PrintPage;
PrintPreviewDialog previewDialog = new PrintPreviewDialog();
previewDialog.Document = printDocument;
pageIndex = 0;
printDocument.DefaultPageSettings.PrinterSettings.PrintToFile = true;
string path = "d:\\BillIng.xps";
if (File.Exists(path))
File.Delete(path);
printDocument.DefaultPageSettings.PrinterSettings.PrintFileName = "d:\\BillIng.xps";
printDocument.PrintController = new StandardPrintController();
printDocument.Print();
printDocument.PrintPage -= printdoc1_PrintPage;
}
catch { }
}
private static Image cropImage(Image img, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(img);
Bitmap bmpCrop = bmpImage.Clone(cropArea, System.Drawing.Imaging.PixelFormat.DontCare);
return (Image)(bmpCrop);
}
}
}