how to fill C# Fill rectangle From bottom to top? - c#

I have drawn vertical Rectangle but i want to fill it from bottom to top.
here is the code i used
System.Drawing.Drawing2D.LinearGradientBrush linGrBrush =
new System.Drawing.Drawing2D.LinearGradientBrush(
new Point(0, 12),
new Point(0,2),
Color.FromArgb(0, 0, 0, 0),
Color.FromArgb(255, 190, 0, 0));
Pen pen = new Pen(linGrBrush);
e.Graphics.FillRectangle(linGrBrush,groupBox2.Width -50,10, 25, x);
using (Pen Pen1 = new Pen(Color.BurlyWood, 4))
{
e.Graphics.DrawRectangle(Pen1, groupBox2.Width -50,10, 25, 200);
}
x is color fill offset which fill is used to fill rectangle after every 2 seconds.

I think that you should adjust the starting and the ending points of the gradient:
System.Drawing.Drawing2D.LinearGradientBrush linGrBrush =
new System.Drawing.Drawing2D.LinearGradientBrush(
new Point(0, 1),
new Point(0,0),
Color.FromArgb(0, 0, 0, 0),
Color.FromArgb(255, 190, 0, 0));

Related

Multi-color gradient does not show all colors

I have a multicolor gradient it consists of 14 colors. Here is my code:
panel1.Paint += new PaintEventHandler(panel1_Paint);
panel1.Refresh();
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
LinearGradientBrush br = new LinearGradientBrush(this.ClientRectangle, Color.FromArgb(255, 0, 0, 0), Color.FromArgb(255, 100, 100, 200),0, false);
System.Drawing.Drawing2D.ColorBlend cb = new System.Drawing.Drawing2D.ColorBlend();
cb.Positions = new[] { 0, 1 /15f, 2 / 15f, 3 / 15f, 4 / 15f, 5 / 15f, 6 / 15f, 7 / 15f, 8 / 15f, 9 / 15f, 10 / 15f, 11 / 15f, 12 / 15f, 13 / 15f,1 };
cb.Colors = new[] {
Color.FromArgb(255, 0, 0, 0),
Color.FromArgb(255, 0, 0, 50),
Color.FromArgb(255, 10, 10, 100),
Color.FromArgb(255, 30, 30, 100),
Color.FromArgb(255, 70, 70,200),
Color.FromArgb(255, 100, 100, 255),
Color.FromArgb(255, 170, 170, 255),
Color.FromArgb(255, 55, 151, 107),
Color.FromArgb(255, 117, 194, 103),
Color.FromArgb(255, 230, 230, 128),
Color.FromArgb(255, 202, 157, 75),
Color.FromArgb(255, 185, 154, 100),
Color.FromArgb(255, 220, 220, 220),
Color.FromArgb(255, 255, 255, 255),
Color.FromArgb(255, 100, 100, 200) };
br.InterpolationColors = cb;
// rotate
br.RotateTransform(90);
// paint
g.FillRectangle(br, this.ClientRectangle);
}
Unfortunately it does not show all the colors. My rectangle's height is 100 but it shows a gradient like this:
What is wrong and how can I fix it?
If you want to fill the Rectangle Vertical, you should specify the Rotation in the constructor of your LinearGradientBrush:
new LinearGradientBrush(this.ClientRectangle, colorFrom, colorTo, 90, false);
Here --^
And remove the Transformation
br.RotateTransform(90);
Since the width and height of the ClientRectangle are basically swapped by your current implementation (because of the 90° rotation), you either see only a small part of the gradient or the entire gradient multiple times.
This also doesn't work because you use the wrong ClientRectangle. You are using this.ClientRectangle in your Form's code-behind. Replace every this.ClientRectangle with panel1.ClientRectangle.
How this should look:
How your unmodified code looked:

Print with Task

I'm creating a label with Graphics and printing it with PrintDocument, before i didn't had any problems because the information on the label was repeated multiple times so i would just set copies and everything would work fine.
But now each label has a different information so it freezes the ui because i have to loop PrintDocument.Print() multiple times instead of setting copies.
i tried:
Task t = new Task(() =>
{
for (int i = 0; i < Copies; i++)
{
printDocument1.Print();
Label_Copies++;
}
});
t.Start();
I'm drawing the label on printDocument1_PrintPage with this code:
int base_y = 5;
int base_x = 7;
int fontsize_bold = 8;
int fontsize_regular = 7;
RectangleF baserect = new RectangleF(base_x, base_y + 20, 0, 0);
SolidBrush whiteBrush = new SolidBrush(System.Drawing.Color.White);
SolidBrush blackBrush = new SolidBrush(System.Drawing.Color.Black);
string font = "Cabriolli";
Pen mypen = new Pen(blackBrush);
e.Graphics.FillRectangle(whiteBrush, new Rectangle(0, 0, 320, 130));
//e.Graphics.DrawRectangle(mypen, 1, 1, 225, 140);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawString("REMETENTE:",
new Font(font, fontsize_regular, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x, base_y, 0, 0));
base_y += 10;
e.Graphics.DrawString("BETA COMERCIAL IMPORTADORA LTDA",
new Font(font, fontsize_bold, System.Drawing.FontStyle.Bold),
Brushes.Black, new RectangleF(base_x, base_y, 0, 0));
base_y += 15;
e.Graphics.DrawString("DESTINATARIO:",
new Font(font, fontsize_regular, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x, base_y, 0, 0));
base_y += 10;
e.Graphics.DrawString(Etiqueta_Destinatario, // *cliente
new Font(font, fontsize_bold, System.Drawing.FontStyle.Bold),
Brushes.Black, new RectangleF(base_x, base_y, 0, 0));
base_y += 15;
e.Graphics.DrawString("NOTA FISCAL:",
new Font(font, fontsize_regular, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x, base_y + 3, 0, 0));
e.Graphics.DrawString(Etiqueta_Nota, // *nota
new Font(font, 10, System.Drawing.FontStyle.Bold),
Brushes.Black, new RectangleF(base_x + 68, base_y, 0, 0));
base_y += 15;
e.Graphics.DrawString("PEDIDO:",
new Font(font, fontsize_regular, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x, base_y + 3, 0, 0));
e.Graphics.DrawString(Etiqueta_Pedido, // *pedido
new Font(font, 10, System.Drawing.FontStyle.Bold),
Brushes.Black, new RectangleF(base_x + 43, base_y, 0, 0));
base_y += 15;
e.Graphics.DrawString("Etiqueta numero:",
new Font(font, fontsize_regular, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x + 140, base_y - 20, 0, 0));
if (Copias.Checked)
{
e.Graphics.DrawString(Etiqueta_Copias.ToString(),
new Font(font, 15, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x + 140, base_y, 0, 0));
}
else
{
e.Graphics.DrawString(Etiqueta_Copia.ToString(),
new Font(font, 15, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x + 140, base_y, 0, 0));
}
e.Graphics.DrawString("VOLUMES:",
new Font(font, fontsize_regular, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x, base_y + 3, 0, 0));
e.Graphics.DrawString(peças_textbox.Text, // *quantidade
new Font(font, 10, System.Drawing.FontStyle.Bold),
Brushes.Black, new RectangleF(base_x + 53, base_y, 0, 0));
base_y += 25;
e.Graphics.DrawString("TRANSPORTADORA:",
new Font(font, fontsize_regular, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x, base_y, 0, 0));
base_y += 14;
e.Graphics.DrawString(nota_transportadora_combobox.Text, // *transportadora
new Font(font, 10, System.Drawing.FontStyle.Bold),
Brushes.Black, new RectangleF(base_x, base_y, 0, 0));
whiteBrush.Dispose();
blackBrush.Dispose();
mypen.Dispose();
but it doesn't work is there a way to fix it?
-the information comes from the ui
-500~ labels
-the only information that changes from label to label in those copies is
if (Copias.Checked)
{
e.Graphics.DrawString(Etiqueta_Copias.ToString(),
new Font(font, 15, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x + 140, base_y, 0, 0));
}
else
{
e.Graphics.DrawString(Etiqueta_Copia.ToString(),
new Font(font, 15, System.Drawing.FontStyle.Regular),
Brushes.Black, new RectangleF(base_x + 140, base_y, 0, 0));
}
its basically a counter for the label number...
As I see it, your code, if we ignore the printer's spooling side, is pure WinForms UI.
Since that the work is multiplied, let's say by a 100 copies, it becomes too much Continous UI.
Tasking isn't helping you because I think the printing side is "fire and forget", so even if the printing took 30 seconds per sticker, the printing side would return immediately, and let the UI start it's heavy work on the next sticker, almost immediately after it finishes the last one.
let's say the UI has to work 1 second per sticker, you are looking at a 100 seconds UI blocking...
My suggestion:
Rely on the fact that the printing behind takes 20 seconds: Launch the printing using a timer instead of a loop. Set it to 5, 10 or 20 seconds (match with your printer's speed). Each time you will fire the timer, it will UI process 1 sticker only, and then rest in peace for 5, 10, or 20 seconds...

Draw clockwise filled in circle

I'm trying to make a cooldown visual for my game when actions are used. I want the button that I have that is the action to be filled with a grayish semi-transparent color that "unwinds" clockwise (if that makes sense). Games like World of Warcraft do this where the time it takes for the cooldown is the time the angle of the unwinding takes. You can see an example here. In this picture the cooldown is more than 1/2 way finished.
http://www.vbforums.com/attachment.php?attachmentid=101705&stc=1&d=1372575930
I'm playing around with arc drawing but this doesn't give me what I'm after.
if (globalCD)
{
Pen p = new Pen(Color.FromArgb(125, 255, 0, 0), 10);
//e.Graphics.DrawLine(p, new Point(0, 0), new Point(10, 10));
e.Graphics.DrawArc(p, new Rectangle(0, 0, 64, 64), 270, 270);
}
In general, the Graphics class has a FillX method for each DrawX method. In this case the result is sufficiently different that the names actually change a bit, but you likely want the FillPie method.
if (globalCD)
{
Pen p = new Pen(Color.FromArgb(125, 255, 0, 0), 10);
//e.Graphics.DrawLine(p, new Point(0, 0), new Point(10, 10));
e.Graphics.FillPie(p, new Rectangle(0, 0, 64, 64), 270, 270);
}

color blending using PathGradientBrush

I have been stuck at this problem for few hours but can n't seem to make progress. I am trying to draw a rectangle which shows like the following
with a lightgrey border line. I am successfully able to draw the grey border line rectangle, but i am having trouble filling the rectangle.
There are 9 colors and i would like them to be space equally across the width of my rectangle.
My Code Looks like the following
using (var gp = new GraphicsPath())
{
gp.AddRectangle(rect);
using (var pgb = new PathGradientBrush(gp))
{
var pos = new[] { 0f, .125f, .25f, .375f, .5f, .625f, .75f, .875f, 1f };
var b = new Blend
{
Positions = pos,
Factors = new[] { .125f, .125f, .125f, .125f, .125f, .125f, .125f, .125f, .125f }
};
var cb = new ColorBlend
{
Positions = pos,
Colors = new[]
{
Color.FromArgb(0, 0, 0),
Color.FromArgb(0, 0, 79),
Color.FromArgb(81, 0, 123),
Color.FromArgb(152, 0, 118),
Color.FromArgb(211, 0, 62),
Color.FromArgb(245, 31, 0),
Color.FromArgb(255, 175, 0),
Color.FromArgb(255, 255, 100),
Color.FromArgb(255, 255, 255),
}
};
pgb.Blend = b;
pgb.InterpolationColors = cb;
pgb.CenterPoint = new PointF(rect.Width / 2, rect.Height / 2);
pgb.FocusScales = new PointF(.5f, .5f);
bufferedGraphics.Graphics.FillPath(pgb, gp);
}
}
but this ends up producing
Please ignore the inconsistent sizes of the two graphics.
Is this possible to do and if so how can i change my method to accomplish this ?
Instead of using the PathGradientBrush, use a LinearGradientBrush, because you want to draw the colors in a straight block. And (at least for me) it's easier to understand what happens.
I've tried the following code in a framework 2.0 project, s sorry for removing C#4.0 syntax.
using (LinearGradientBrush lgb = new LinearGradientBrush(rect, Color.Black, Color.White, 0f)) {
float[] pos = new float[] { 0f, .125f, .25f, .375f, .5f, .625f, .75f, .875f, 1f };
Blend b = new Blend();
b.Positions = pos;
b.Factors = new float[] { .125f, .125f, .125f, .125f, .125f, .125f, .125f, .125f, .125f };
ColorBlend cb = new ColorBlend();
cb.Positions = pos;
cb.Colors = new Color[] {
Color.FromArgb(0, 0, 0),
Color.FromArgb(0, 0, 79),
Color.FromArgb(81, 0, 123),
Color.FromArgb(152, 0, 118),
Color.FromArgb(211, 0, 62),
Color.FromArgb(245, 31, 0),
Color.FromArgb(255, 175, 0),
Color.FromArgb(255, 255, 100),
Color.FromArgb(255, 255, 255),
};
lgb.Blend = b;
lgb.InterpolationColors = cb;
e.Graphics.FillRectangle(lgb, rect);
}
Result:

How to draw with replacement instead of blending

I'm trying to "draw" areas of transparency onto a bitmap -- like cutting holes in the image.
The following code does not draw a line of transparency because drawing a transparent line onto a bitmap of course blends instead of replaces. (Why the default is to do the more complicated of the two drawing operations, makes no sense.)
Bitmap myBitmap = new Bitmap(50, 50);
Graphics g = Graphics.FromImage(myBitmap);
g.FillRectangle(Brushes.Black, 0, 0, 50, 50);
g.FillEllipse(Brushes.Transparent, 25, 0, 25, 25); //Does nothing
g.DrawLine(Pens.Transparent, 0, 0, 50, 50); //Does nothing
How would I modify this so that a transparent circle and line replace what's in the bitmap instead of blending?
(Note that this is the trivial case of "drawing" complete transparency. The end I'm going toward is the ability to "draw" modifying the alpha channel only without creating my own pixel by pixel operation. Being able to do complete transparency will suffice though.)
Following answer in article suggested as a duplicate, I've also tried the following (which does not work)
base.OnPaint(e);
Bitmap myBitmap = new Bitmap(50, 50);
e.Graphics.FillRectangle(Brushes.Black, 0, 0, 50, 50);
Graphics g = Graphics.FromImage(myBitmap);
g.FillEllipse(new SolidBrush(Color.FromArgb(150, 125, 125, 125)), 25, 0, 25, 25);
g.DrawLine(new Pen(Color.FromArgb(150,25,25,25)), 0, 0, 50, 50);
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
e.Graphics.DrawImage(myBitmap, 0, 0);
also tested this with SourceCopy
This works totally fine for me
Bitmap bmp = new Bitmap(50, 50, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
using (Graphics g = Graphics.FromImage(bmp))
{
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
g.FillRectangle(Brushes.Black, 0, 0, 50, 50);
g.FillEllipse(Brushes.Transparent, 25, 0, 25, 25);
g.DrawLine(Pens.Transparent, 0, 0, 50, 50);
g.Flush();
}
bmp.Save("Test.bmp");

Categories

Resources