why I do not display signals in windows forms? - c#

Let's write a C# program of type "Windows Forms Application" to create a
application simulating the modulation and amplitude demodulation of signal transmission
Analog.
The carrier signal, the modulator signal, the modulated signal will be graphically displayed/
demodulated and the function of spectral density of signals.
I tried to color the picture boxes and they are displayed, but not their content.
My goal is to draw the 4 lines which I want to display in the 4 Picture boxes.
How can I modify this code to get the spec waveformsifice modulation and demodulation in amplitude of an analog signal?
My code:
using System;
using System.Windows.Forms;
using System.Drawing;
using static System.Math;
static class Program
{
[STAThread]
public static void Main()
{
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new ModulationDemodulationExample());
Application.EnableVisualStyles();
}
}
public class ModulationDemodulationExample : Form
{
// Declare controls and variables
private const int SignalLength = 100;
private PictureBox carrierSignalBox = new PictureBox();
private PictureBox modulatorSignalBox = new PictureBox();
private PictureBox modulatedSignalBox = new PictureBox();
private PictureBox demodulatedSignalBox = new PictureBox();
private double[] carrierSignal = new double[SignalLength];
private double[] modulatorSignal = new double[SignalLength];
private double[] modulatedSignal = new double[SignalLength];
private double[] demodulatedSignal = new double[SignalLength];
private double carrierFrequency = 2.0;
private Bitmap carrierSignalBmp;
private Bitmap modulatorSignalBmp;
private Bitmap modulatedSignalBmp;
private Bitmap demodulatedSignalBmp;
public ModulationDemodulationExample()
{
InitializeComponent();
}
private void InitializeComponent()
{
// Initialize form and controls
Text = "Modulation and Demodulation Simulator";
Size = new Size(800, 600);
PictureBox carrierSignalBox = new PictureBox()
{
Location = new Point(10, 10),
Size = new Size(360, 180),
Visible = true,
Name = "Carrier Signal"
};
PictureBox modulatorSignalBox = new PictureBox()
{
Location = new Point(10, 200),
Size = new Size(360, 180),
Visible = true,
Name = "Modulator Signal"
};
PictureBox modulatedSignalBox = new PictureBox()
{
Location = new Point(400, 10),
Size = new Size(360, 180),
Visible = true,
Name = "Modulated Signal"
};
PictureBox demodulatedSignalBox = new PictureBox()
{
Location = new Point(400, 200),
Size = new Size(360, 180),
Visible = true,
Name = "Demodulated Signal"
};
Controls.Add(carrierSignalBox);
Controls.Add(modulatorSignalBox);
Controls.Add(modulatedSignalBox);
Controls.Add(demodulatedSignalBox);
GenerateSignal();
CreateBitmaps();
DrawSignals();
}
private void GenerateSignal()
{
for (int i = 0; i < SignalLength; i++)
{
carrierSignal[i] = Math.Sin(2 * Math.PI * carrierFrequency * i);
modulatorSignal[i] = Math.Sin(2 * Math.PI * i);
modulatedSignal[i] = carrierSignal[i] * modulatorSignal[i];
demodulatedSignal[i] = modulatedSignal[i] * carrierSignal[i];
}
}
private void CreateBitmaps()
{
carrierSignalBmp = new Bitmap(carrierSignalBox.Width, carrierSignalBox.Height);
modulatorSignalBmp = new Bitmap(modulatorSignalBox.Width, modulatorSignalBox.Height);
modulatedSignalBmp = new Bitmap(modulatedSignalBox.Width, modulatedSignalBox.Height);
demodulatedSignalBmp = new Bitmap(demodulatedSignalBox.Width, demodulatedSignalBox.Height);
//carrierSignalBox.Image = carrierSignalBmp;
carrierSignalBox.DrawToBitmap(carrierSignalBmp, carrierSignalBox.ClientRectangle);
modulatorSignalBox.Image = modulatorSignalBmp;
modulatedSignalBox.Image = modulatedSignalBmp;
demodulatedSignalBox.Image = demodulatedSignalBmp;
}
private void DrawSignals()
{
DrawSignal(carrierSignalBox, carrierSignal, Color.Blue);
DrawSignal(modulatorSignalBox, modulatorSignal, Color.Red);
DrawSignal(modulatedSignalBox, modulatedSignal, Color.Green);
DrawSignal(demodulatedSignalBox, demodulatedSignal, Color.Black);
}
void DrawSignal(PictureBox pictureBox, double[] signal, Color color)
{
// Get the graphics object for the PictureBox
var graphics = pictureBox.CreateGraphics();
// Clear the PictureBox
graphics.Clear(Color.White);
// Set the pen color
var pen = new Pen(color);
// Scale the signal's values to the size of the PictureBox
var yScale = (double)pictureBox.Height / 2.0;
var xScale = (double)pictureBox.Width / (double)signal.Length;
// Draw the signal
for (int i = 0; i < signal.Length - 1; i++)
{
var x1 = (int)(i * xScale);
var y1 = (int)(yScale + (signal[i] * yScale));
var x2 = (int)((i + 1) * xScale);
var y2 = (int)(yScale + (signal[i + 1] * yScale));
graphics.DrawLine(pen, x1, y1, x2, y2);
}
}
}
I created the 4 signals but I can not display them in form ,I would have liked each signal to be displayed in the PictureBox.

You can change your program with an override Paint method for each PictureBox like this
public partial class ModulationDemodulationExample : Form
{
// Declare controls and variables
private const int SignalLength = 100;
private PictureBox carrierSignalBox = new PictureBox();
private PictureBox modulatorSignalBox = new PictureBox();
private PictureBox modulatedSignalBox = new PictureBox();
private PictureBox demodulatedSignalBox = new PictureBox();
private double[] carrierSignal = new double[SignalLength];
private double[] modulatorSignal = new double[SignalLength];
private double[] modulatedSignal = new double[SignalLength];
private double[] demodulatedSignal = new double[SignalLength];
private double carrierFrequency = 2.0;
public ModulationDemodulationExample()
{
InitializeComponent();
// Initialize form and controls
Text = "Modulation and Demodulation Simulator";
Size = new Size(800, 600);
PictureBox carrierSignalBox = new PictureBox()
{
Location = new Point(10, 10),
Size = new Size(360, 180),
Visible = true,
Name = "Carrier Signal"
};
carrierSignalBox.Paint += new PaintEventHandler(carrierSignalBox_Paint);
PictureBox modulatorSignalBox = new PictureBox()
{
Location = new Point(10, 200),
Size = new Size(360, 180),
Visible = true,
Name = "Modulator Signal"
};
modulatorSignalBox.Paint += new PaintEventHandler(modulatorSignalBox_Paint);
PictureBox modulatedSignalBox = new PictureBox()
{
Location = new Point(400, 10),
Size = new Size(360, 180),
Visible = true,
Name = "Modulated Signal"
};
modulatedSignalBox.Paint += new PaintEventHandler(modulatedSignalBox_Paint);
PictureBox demodulatedSignalBox = new PictureBox()
{
Location = new Point(400, 200),
Size = new Size(360, 180),
Visible = true,
Name = "Demodulated Signal"
};
demodulatedSignalBox.Paint += new PaintEventHandler(demodulatedSignalBox_Paint);
Controls.Add(carrierSignalBox);
Controls.Add(modulatorSignalBox);
Controls.Add(modulatedSignalBox);
Controls.Add(demodulatedSignalBox);
GenerateSignal();
}
private void GenerateSignal()
{
for (int i = 0; i < SignalLength; i++)
{
carrierSignal[i] = Math.Sin(2 * Math.PI * carrierFrequency * i);
modulatorSignal[i] = Math.Sin(2 * Math.PI * i);
modulatedSignal[i] = carrierSignal[i] * modulatorSignal[i];
demodulatedSignal[i] = modulatedSignal[i] * carrierSignal[i];
}
}
private void carrierSignalBox_Paint(object? sender, PaintEventArgs e)
{
DrawSignal(e.Graphics, carrierSignalBox, carrierSignal, Color.Blue);
}
private void modulatorSignalBox_Paint(object? sender, PaintEventArgs e)
{
DrawSignal(e.Graphics, modulatorSignalBox, modulatorSignal, Color.Red);
}
private void modulatedSignalBox_Paint(object? sender, PaintEventArgs e)
{
DrawSignal(e.Graphics, modulatedSignalBox, modulatedSignal, Color.Green);
}
private void demodulatedSignalBox_Paint(object? sender, PaintEventArgs e)
{
DrawSignal(e.Graphics, demodulatedSignalBox, demodulatedSignal, Color.Black);
}
void DrawSignal(Graphics graphics, PictureBox pictureBox, double[] signal, Color color)
{
// Get the graphics object for the PictureBox
//var graphics = pictureBox.CreateGraphics();
// Clear the PictureBox
graphics.Clear(Color.White);
// Set the pen color
var pen = new Pen(color);
// Scale the signal's values to the size of the PictureBox
var yScale = (double)pictureBox.Height / 2.0;
var xScale = (double)pictureBox.Width / (double)signal.Length;
// Draw the signal
for (int i = 0; i < signal.Length - 1; i++)
{
var x1 = (int)(i * xScale);
var y1 = (int)(yScale + (signal[i] * yScale));
var x2 = (int)((i + 1) * xScale);
var y2 = (int)(yScale + (signal[i + 1] * yScale));
graphics.DrawLine(pen, x1, y1, x2, y2);
}
}
}
When you want to redraw the PictureBox, just call the Invalidate method and the Paint event is automatically called. Example:
carrierSignalBox.Invalidate()

Related

How to let pictureboxes not overlap with each other?

So I made a game for a school project in windows forms. Only problem is, is that my pictures are overlapping with each other. So my question how do I get them all on a different location where they don't touch each other or not overlap?
In this Method I create the zombies and here I just choose for random locations between -100 and 0 on the x-as
public void ZombieMaker(int aantal, Form formInstance, string ZombieDik)
{
for (int i = 0; i < aantal; i++)
{
PictureBox picture = new PictureBox();
picture.Image = Properties.Resources.ZombieDik;
picture.Size = new Size(200, 200);
picture.Location = new Point(random.Next(1500), random.Next(-100,0));
picture.SizeMode = PictureBoxSizeMode.Zoom;
picture.Click += zombie_Click;
picture.BackColor = Color.Transparent;
formInstance.Controls.Add(picture);
picture.Tag = zombies[i];
}
}
pic of zombies overlapping
Keep track of the already placed pictureboxes, and validate if the bound would overlap.
//List of all pictureBoxes
private List<PictureBox> _pictureBoxes = new List<PictureBox>();
public void ZombieMaker(int aantal, Form formInstance, string ZombieDik)
{
for (int i = 0; i < aantal; i++)
{
Rectangle newPosition;
//loop till you found a new position
while (true)
{
var newPoint = new Point(random.Next(1500), random.Next(-100,0));
var newSize = new Size(200, 200);
newPosition = new Rectangle(newPoint, newSize);
//validate the newPosition
if (!_pictureBoxes.Any(x => x.Bounds.IntersectsWith(newPosition)))
{
//break the loop when there isn't an overlapping rectangle found
break;
}
}
PictureBox picture = new PictureBox();
_pictureBoxes.Add(picture);
picture.Image = Properties.Resources.ZombieDik;
picture.Size = newPosition.Size;
picture.Location = newPosition.Location;
...
}
}
To validate the overlapping I am using the IntersectWith method of the Rectangle class
https://learn.microsoft.com/en-us/dotnet/api/system.drawing.rectangle.intersectswith?view=net-6.0#system-drawing-rectangle-intersectswith(system-drawing-rectangle)
Edit:
Here a do/while loop instead of the while loop.
Rectangle newPosition;
do
{
var newPoint = new Point(random.Next(1500), random.Next(-100,0));
var newSize = new Size(200, 200);
newPosition = new Rectangle(newPoint, newSize);
} while(_pictureBoxes.Any(x => x.Bounds.IntersectsWith(newPosition))
I fixed your code so the picture boxes do not overlap each other:
public void ZombieMaker(int aantal, Form formInstance, string ZombieDik)
{
for (int i = 0; i < aantal; i++)
{
PictureBox picture = new PictureBox();
picture.Image = Properties.Resources.ZombieDik;
picture.Size = new Size(200, 200);
picture.Location = new Point(picture.Width * i, random.Next(-100,0));
picture.SizeMode = PictureBoxSizeMode.Zoom;
picture.Click += zombie_Click;
picture.BackColor = Color.Transparent;
formInstance.Controls.Add(picture);
picture.Tag = zombies[i];
}
}

how to make diagram fit with in panel?

hey i am trying to build a windows application in .net,i have to draw factorial image inside the panel
private void Canvas_Paint(object sender, PaintEventArgs e)
{
start_x = Canvas.Width / 2;
start_Y = Canvas.Height / 2;
for (int i = 0; i < 400; i++)
draw_T();
}
public void draw_T()
{
mypen = new Pen(Color.Green, 2F);
my_angle = my_angle + (45);
my_length = 100 + (1);
end_x = (int)(start_x + Math.Cos(my_angle * .0174539676) * my_length);
end_Y = (int)(start_Y + Math.Sin(my_angle * .0174539676) * my_length);
Point[] points =
{
new Point (start_x,start_Y),
new Point (end_x,end_Y)
};
Point[] points1 =
{
new Point ((end_x+start_x)/2,(end_Y+start_Y)/2),
new Point (end_x+50,end_Y-100)
};
start_x = end_x;
start_Y = end_Y;
Graphics g = Canvas.CreateGraphics();
g.DrawLines(mypen, points);
g.DrawLines(mypen, points1);
}
drawing T shape line,then i start to draw another T shape from last end points .But problem is diagram is going outside of the panel.How do i fix drawing inside the panel

Drawing rectangles on chart C#

I'm new to C# and I want to draw some rectangles on a chart (System.Windows.Forms.DataVisualization.Charting.Chart). I've tried looking at some tutorials, althought most of them are about drawing on a form and not on a chart.
Here is some code I've made based on some tutorials. It does not work, the chart simply goes blank.
public partial class Form1 : Form
{
private RectangleF r1;
private RectangleF r2;
public Form1()
{
r1.X = 10;
r1.Y = 10;
r1.Width = 20;
r1.Height = 20.5F;
r1.X = 100;
r1.Y = 100;
r1.Width = 200;
r1.Height = 300;
System.Windows.Forms.DataVisualization.Charting.Chart chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
InitializeComponent();
this.chart1.PostPaint += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs>(this.PostPaint);
}
private void PostPaint(object sender, System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs e)
{
e.ChartGraphics.GetAbsoluteRectangle(r1);
}
}
In this example I've created as well, only the second rectangle is drawn and the chart shows no axis at all. I want to draw multiples triangles using floats.
public partial class Form1 : Form
{
private Rectangle r1;
private Rectangle r2;
public Form1()
{
r1.X = 10;
r1.Y = 10;
r1.Width = 20;
r1.Height = 20;
r1.X = 100;
r1.Y = 100;
r1.Width = 200;
r1.Height = 300;
System.Windows.Forms.DataVisualization.Charting.Chart chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
InitializeComponent();
this.chart1.PostPaint += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs>(this.PostPaint);
}
private void PostPaint(object sender, System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs e)
{
e.ChartGraphics.Graphics.DrawRectangle(new Pen(Color.Red, 3), r1);
e.ChartGraphics.Graphics.DrawRectangle(new Pen(Color.Black, 5), r2);
}
}
In both examples, you're setting the values for r1 twice instead of r1 and r2.
In your first example, GetAbsoluteRectangle does not draw a rectangle. It is used for converting coordinates. You should use DrawRectangle like you are in the second example.
Simply change
r1.X = 100;
r1.Y = 100;
r1.Width = 200;
r1.Height = 300;
By that :
r2.X = 100;
r2.Y = 100;
r2.Width = 200;
r2.Height = 300;
It will - normaly - works fine.

saving drawn image into folder

I have drawn an image in pictureBox, now i want to save it in the folder. I have tried so many ways nothing worked. I am drawing image using the fallowing code. I am drawing the image based on Textbox values.
private void btnTransferBottleRegenerate_Click(object sender, EventArgs e)
{
float[] volumetransfer = new float[1];
volumetransfer[0] = float.Parse(txtTransferVolume.Text);
int[] percentages = new int[6];
percentages[0] = int.Parse(txtTransferNotIdentified.Text);
percentages[1] = int.Parse(txtTransferWaterBasedMud.Text);
percentages[2] = int.Parse(txtTransferOilBasedMud.Text);
percentages[3] = int.Parse(txtTransferWater.Text);
percentages[4] = int.Parse(txtTransferHydrocarbonLiq.Text);
percentages[5] = int.Parse(txtTransferGas.Text);
Color[] colors = new Color[6];
colors[0] = Color.Gray;
colors[1] = Color.Chocolate;
colors[2] = Color.SaddleBrown;
colors[3] = Color.Blue;
colors[4] = Color.Red;
colors[5] = Color.Lime;
// Finally, call the method
DrawPercentages(percentages, colors, volumetransfer);
//string filename = Application.StartupPath + "\\volumetransfer.jpg";
// pictureBox1.Image.Save(Application.StartupPath + "\\Image\\picture1.jpg");
// pictureBox1.Refresh();
// if (pictureBox1 != null)
// {
pictureBox1.Image.Save(Application.StartupPath + "\\test.bmp");
// }
}
private void DrawPercentages(int[] percentages, Color[] colors, float[] volumetransfer)
{
// Create a Graphics object to draw on the picturebox
Graphics G = pictureBox1.CreateGraphics();
// Calculate the number of pixels per 1 percent
float pixelsPerPercent = pictureBox1.Height / volumetransfer[0];
// Keep track of the height at which to start drawing (starting from the bottom going up)
int drawHeight = pictureBox1.Height;
// Loop through all percentages and draw a rectangle for each
for (int i = 0; i < percentages.Length; i++)
{
// Create a brush with the current color
SolidBrush brush = new SolidBrush(colors[i]);
// Update the height at which the next rectangle is drawn.
drawHeight -= (int)(pixelsPerPercent * percentages[i]);
// Draw a filled rectangle
G.FillRectangle(brush, 0, drawHeight, pictureBox1.Width, pixelsPerPercent * percentages[i]);
}
}
}
}
when I click "Regenerate" button then it is going to draw the image in pictureBox after that i want to save it in a folder. I have the design like this.
A solution is draw on a bitmap, set it as the image of the PictureBox and then save it:
private void DrawPercentages(int[] percentages, Color[] colors, float[] volumetransfer){
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
using(Graphics G = Graphics.FromImage(bmp)){
//...
}
pictureBox1.Image = bmp;
}
And then your code should work perfectly without any problem.
First, you should paint within the correct event PictureBox1_Paint so that your drawn image stays visible (better: got repaint) even if your window gets eg: resized.
Afterwards you could make use of a snippet posted by #Hans Passant - How to save Graphics object to save your drawn image to disk.
// global to be accesible within paint
float[] volumetransfer = new float[1];
int[] percentages = new int[6];
Color[] colors = new Color[6];
private void btnTransferBottleRegenerate_Click(object sender, EventArgs e)
{
/// initialization goes here
// force pictureBox to be redrawn
// so resizing your window won't let your rectangles disapear
pictureBox1.Invalidate();
using (var bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height))
{
pictureBox1.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
bmp.Save(#"e:\temp\test.png"); //Application.StartupPath + "\\Image\\picture1.jpg"
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
// use GraphicsObject of PaintEventArgs
Graphics G = e.Graphics;
float pixelsPerPercent = pictureBox1.Height / volumetransfer[0];
int drawHeight = pictureBox1.Height;
for (int i = 0; i < percentages.Length; i++)
{
SolidBrush brush = new SolidBrush(colors[i]);
drawHeight -= (int)(pixelsPerPercent * percentages[i]);
G.FillRectangle(brush, 0, drawHeight, pictureBox1.Width, pixelsPerPercent * percentages[i]);
}
}
On the other hand your DrawPercentage(..) could return a new Image - which you could afterwards assign to the pictureBox and save it with pictureBox1.Image.Save(...)
private void button1_Click(object sender, EventArgs e)
{
float[] volumetransfer = new float[1];
int[] percentages = new int[6];
Color[] colors = new Color[6];
/// initialization goes here
pictureBox1.Image = CreateImage(volumetransfer, percentages, colors);
pictureBox1.Image.Save(#"e:\temp\test.png");
}
private Image CreateImage(float[] volumetransfer, int[] percentages, Color[] colors)
{
Image img = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(img);
float pixelsPerPercent = pictureBox1.Height / volumetransfer[0];
int drawHeight = pictureBox1.Height;
for (int i = 0; i < percentages.Length; i++)
{
SolidBrush brush = new SolidBrush(colors[i]);
drawHeight -= (int)(pixelsPerPercent * percentages[i]);
g.FillRectangle(brush, 0, drawHeight, pictureBox1.Width, pixelsPerPercent * percentages[i]);
}
return img;
}

How to print one large image in many pages?

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);
}
}
}

Categories