I want to create a bitmap of size 160*160 and split it into four squares with each square filled with one color. How can this be done?
Just in case anyone needs a method solving this specific problem in a more general way, I wrote an extension method, taking colors and an integer that states how many tiles it should split off in x and y direction:
public static void FillImage(this Image img, int div, Color[] colors)
{
if (img == null) throw new ArgumentNullException();
if (div < 1) throw new ArgumentOutOfRangeException();
if (colors == null) throw new ArgumentNullException();
if (colors.Length < 1) throw new ArgumentException();
int xstep = img.Width / div;
int ystep = img.Height / div;
List<SolidBrush> brushes = new List<SolidBrush>();
foreach (Color color in colors)
brushes.Add(new SolidBrush(color));
using (Graphics g = Graphics.FromImage(img))
{
for (int x = 0; x < div; x++)
for (int y = 0; y < div; y++)
g.FillRectangle(brushes[(y * div + x) % colors.Length],
new Rectangle(x * xstep, y * ystep, xstep, ystep));
}
}
The four squares, the OP wanted would be produced with:
new Bitmap(160, 160).FillImage(2, new Color[]
{
Color.Red,
Color.Blue,
Color.Green,
Color.Yellow
});
You can try something like
using (Bitmap b = new Bitmap(160, 160))
using (Graphics g = Graphics.FromImage(b))
{
g.FillRectangle(new SolidBrush(Color.Blue), 0, 0, 79, 79);
g.FillRectangle(new SolidBrush(Color.Red), 79, 0, 159, 79);
g.FillRectangle(new SolidBrush(Color.Green), 0, 79, 79, 159);
g.FillRectangle(new SolidBrush(Color.Yellow), 79, 79, 159, 159);
b.Save(#"c:\test.bmp");
}
Related
I am trying to make a Bitmap image to represent a block of one hour and show red as worked time and white as non-worked showing in periods of 10 minutes intervals. I am trying to get the result to look like below:
Any help or guidance would be greater appreciated. In the code below Tuple<int,DateTime>> the int is time block example 0,1,2,3.....21,22,23,24 and DateTime will hold the time worked.
public void DrawPeriod(IGrouping<int, Tuple<int, DateTime>> worked)
{
var bitmap = new Bitmap(640, 480);
for (var x = 0; x < bitmap.Width; x++)
{
for (var y = 0; y < bitmap.Height; y++)
{
bitmap.SetPixel(x, y, Color.Red);
}
}
bitmap.Save("worked.bmp");
}
Sorry I can't give a sample with the data you needed. But you can do it something like this. This can be achieved by using System.Drawing.Graphics.
var sampleData = new int[] { 1, 2, 3, 13, 4, 5, 6, 12, 7, 8, 9 };
var bitmapHeight = 250;
var barWidth = 50;
var bitmap = new Bitmap(sampleData.Length * barWidth, bitmapHeight);
int currentX = 1;
foreach (var item in sampleData)
{
var result = item % 2;
Brush brush;
if (result == 0)
{
brush = Brushes.Red;
}
else
{
brush = Brushes.White;
}
using (Graphics graphics = Graphics.FromImage(bitmap))
{
var rectangle = new Rectangle(currentX, 0, barWidth, bitmapHeight);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.FillRectangle(brush, rectangle);
// Set Text
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
graphics.DrawString(item.ToString(), drawFont, drawBrush, currentX + 15, bitmapHeight / 2);
}
currentX = currentX + 50;
}
// Border
using (Graphics graphics = Graphics.FromImage(bitmap))
{
graphics.DrawRectangle(new Pen(Brushes.Black, 5), new Rectangle(0, 0, bitmap.Width, bitmap.Height));
}
bitmap.Save(FileName);
Sample Output
I am trying to add a black banner on the top and bottom of an image. I can add the banner but the pixel format of the resulted bitmap is changed to 32-bit. Is there any way to get an 8-bit bitmap as a result.
As mentioned here, If I set the 8-bit pixelFormat in the constructor, creating a graphics will raise an exception.
I read that if I convert from 32 to 8, maybe the pixel values will be different than original ones. Don't know if I can create a new bitmap with the desired height and add the black banners's pixels using for loops. Anyone has a better and simple way?
My code is as below:
Bitmap img = image as Bitmap;
using (Bitmap bitmap = new Bitmap(img.Width, img.Height + 200*2)) // create blank bitmap of desired size
using (Graphics graphics = Graphics.FromImage(bitmap))
{
SolidBrush brush = new SolidBrush(Color.White);
graphics.FillRectangle(brush, 0, 0, img.Width,200);
// draw existing image onto new blank bitmap
graphics.DrawImage(img, 0, 200, img.Width, img.Height);
// draw your rectangle below the original image
graphics.FillRectangle(brush, 0, 200 + img.Height, img.Width, 200);
// bitmap.Save(#"c:\Test1.bmp");
}
Here is a routine that does a FillRectangle on a bmp8bpp bitmap.
You pass in an index which, if positive will be used to put the color into the palette. If you pass in a negative index it will try to find the color and if it doesn't find it it will place the color at the end of the index. This will overwrite whatever color was there before!
void FillIndexedRectangle(Bitmap bmp8bpp, Rectangle rect, Color col, int index)
{
var pal = bmp8bpp.Palette;
int idx = -1;
if (index >= 0) idx = index;
else
{
if (pal.Entries.Where(x => x.ToArgb() == col.ToArgb()).Any())
idx = pal.Entries.ToList().FindIndex(x => x.ToArgb() == col.ToArgb());
if (idx < 0) idx = pal.Entries.Length - 1;
}
pal.Entries[idx] = col;
bmp8bpp.Palette = pal;
var bitmapData =
bmp8bpp.LockBits(new Rectangle(Point.Empty, bmp8bpp.Size),
ImageLockMode.ReadWrite, bmp8bpp.PixelFormat);
byte[] buffer=new byte[bmp8bpp.Width*bmp8bpp.Height];
Marshal.Copy(bitmapData.Scan0, buffer,0, buffer.Length);
for (int y = rect.Y; y < rect.Bottom; y++)
for (int x = rect.X; x < rect.Right; x++)
{
buffer[x + y * bmp8bpp.Width] = (byte)idx;
}
Marshal.Copy(buffer, 0, bitmapData.Scan0,buffer.Length);
bmp8bpp.UnlockBits(bitmapData);
}
Example calls:
Bitmap img = new Bitmap(200, 200, PixelFormat.Format8bppIndexed);
FillIndexedRectangle(img, new Rectangle(0,0,200, 200), Color.Silver, 21);
FillIndexedRectangle(img, new Rectangle(23, 23, 55, 99), Color.Red, 22);
FillIndexedRectangle(img, new Rectangle(123, 123, 55, 33), Color.Black, 23);
FillIndexedRectangle(img, new Rectangle(1, 1, 123, 22), Color.Orange, 34);
FillIndexedRectangle(img, new Rectangle(27, 27, 16, 12), Color.Black, -1);
img.Save("D:\\__bmp8bpp.png");
Result:
There is room for improvement:
All error checking in the lockbits is missing, both wrt pixelformat and rectangle data
Adding colors with a more dynamical scheme could be nice instead of adding to the end
A scheme for finding the closest color already in the palette could also be nice
A scheme for drawing with transparency would also be nice. For this all necessary new colors would have to be determined first; also the tranparency mode.
Maybe one should return the index used from the method so the next calls can refer to it..
For other shapes than rectangles one could use a copy routine that first draws them onto a 'normal' 32bpp bitmap and then transfers the pixels to the buffer..
Update: Here are a few lines to add (**) or change (*) to allow drawing unfilled rectangles; stroke 0 fills the rectangle..:
void FillIndexedRectangle(Bitmap bmp8bpp, Rectangle rect,
Color col, int index, int stroke) // *
...
...
Marshal.Copy(bitmapData.Scan0, buffer,0, buffer.Length);
Rectangle ri = rect; //**
if (stroke > 0) ri.Inflate(-stroke, -stroke); //**
for (int y = rect.Y; y < rect.Bottom; y++)
for (int x = rect.X; x < rect.Right; x++)
{
if (ri == rect || !ri.Contains(x,y)) //**
buffer[x + y * bmp8bpp.Width] = (byte)idx;
}
Marshal.Copy(buffer, 0, bitmapData.Scan0,buffer.Length);
I am trying to split an image into 9 equal parts. Like we see in a puzzle game. Image can be any random image. I am trying some code but it is not splitting it into equal parts - it needs coordinate values for rectangles, but I need simple general code to split an image into equal parts.
I've an image. I want to crop it or split into 9 equal parts. But the below code just crops the same part of the image from the right top corner every time.
var imgarray = new Image[9];
var img = Image.FromFile("media\\a.png");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
var index = i * 3 + j;
imgarray[index] = new Bitmap(104, 104);
var graphics = Graphics.FromImage(imgarray[index]);
graphics.DrawImage(img, new Rectangle(0, 0, 104, 104), new Rectangle(i * 104, j * 104, 104, 104), GraphicsUnit.Pixel);
graphics.Dispose();
}
}
Some other tidy ups...
var imgarray = new Image[9];
var img = Image.FromFile("media\\a.png");
for (int i = 0; i < 9; i++)
{
imgarray[i] = new Bitmap(104, 104);
var graphics = Graphics.FromImage(imgarray[i]);
graphics.DrawImage (
img,
new Rectangle(0, 0, 104, 104),
new Rectangle( (i%3) * 104, (i/3) * 104, 104, 104),
GraphicsUnit.Pixel);
graphics.Dispose();
}
}
Hello How to draw a circle with the bitmap. That is, I need to get the image of the circle, using it to draw something.
Use ColorTranslator.FromHtml for this purpose.
This will give you the corresponding System.Drawing.Color:
using (Bitmap btm = new Bitmap(25, 30))
{
using (Graphics grf = Graphics.FromImage(btm))
{
using (Brush brsh = new SolidBrush(ColorTranslator.FromHtml("#ff00ffff")))
{
grf.FillEllipse(brsh, 0, 0, 19, 19);
}
}
}
Or Refer Code:
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g = Graphics.FromImage(bmp);
Pen blackPen = new Pen(Color.Black);
int x = pictureBox1.Width/4;
int y = pictureBox1.Height/4;
int width = pictureBox1.Width / 2;
int height = pictureBox1.Height / 2;
int diameter = Math.Min(width, height);
g.DrawEllipse(blackPen, x, y, diameter, diameter);
pictureBox1.Image = bmp;
If the PictureBox already contains a bitmap, replace the first and second lines with:
Graphics g = Graphics.FromImage(pictureBox1.Image);
Referance Link:
http://www.c-sharpcorner.com/Forums/Thread/30986/
Hope Its Helpful.
Bitmap b = new Bitmap(261, 266);// height & width of picturebox
int xo = 50, yo = 50;// center of circle
double r, rr;
r = 20;
rr = Math.Pow(r, 2);
for (int i = xo - (int)r; i <= xo + r; i++)
for (int j = yo - (int)r; j <= yo + r; j++)
if (Math.Abs(Math.Pow(i - xo, 2) + Math.Pow(j - yo, 2) - rr) <= r)
b.SetPixel(i, j, Color.Black);
pictureBox1.Image = b;
I'm in the process of making my own Captcha check on my website.
Everything's working, except I need some blurryness/effects on my text that's not viewable by a webcrawler etc.
Some of the code used to generate the text on the image:
Bitmap BitMap = new Bitmap(#"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg");
Graphics g = Graphics.FromImage(BitMap);
g.DrawString(""+RandomNumberString+"", new Font("Tahoma", 40), Brushes.Khaki, new PointF(1, 1));
pictureBox1.Image = BitMap;
Example:
What can I do to get my effects/blurryness on my text?
Thank you!
Why roll out your own captcha when reCAPTCHA is free, accessible (through the audio option, making it usable for people with visual issues) and at the same time helps digitize various publications? There's even a .NET implementation.
Edit:
Seeing how it's for fun, having a look at "An ASP.NET Framework for Human Interactive Proofs" might give you some good ideas. Especially the ImageHipChallenge as it includes image distortion code examples.
For example:
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int newX = (int)(x + (distortion * Math.Sin(Math.PI * y / 64.0)));
int newY = (int)(y + (distortion * Math.Cos(Math.PI * x / 64.0)));
if (newX < 0 || newX >= width) newX = 0;
if (newY < 0 || newY >= height) newY = 0;
b.SetPixel(x, y, copy.GetPixel(newX, newY));
}
}
Which will move the pixels in a wave like fashion. Such as in the second word of your example.
Have a look at this tutorial. There you will find a code example on how to create a CAPTCHA using C# and the DrawString method.
Hope, this helps.
I've used this for about 5 years and it doesn't involve any integration with horrid 3rd party APIs.
http://www.codeproject.com/KB/aspnet/CaptchaImage.aspx
protected void Page_Load(object sender, EventArgs e)
{
if(! IsPostBack)
{
LoadCaptcha();[![enter image description here][1]][1]
}
}
public void LoadCaptcha()
{
try
{
Bitmap objBitmap = new Bitmap(130, 60);
Graphics objGraphics = Graphics.FromImage(objBitmap);
objGraphics.Clear(Color.White);
Random objRandom = new Random();
objGraphics.DrawLine(Pens.Black, objRandom.Next(0, 50), objRandom.Next(10, 30), objRandom.Next(0, 200), objRandom.Next(0, 50));
objGraphics.DrawRectangle(Pens.Blue, objRandom.Next(0, 20), objRandom.Next(0, 20), objRandom.Next(50, 80), objRandom.Next(0, 20));
objGraphics.DrawLine(Pens.Blue, objRandom.Next(0, 20), objRandom.Next(10, 50), objRandom.Next(100, 200), objRandom.Next(0, 80));
Brush objBrush =
default(Brush);
//create background style
HatchStyle[] aHatchStyles = new HatchStyle[]
{
HatchStyle.BackwardDiagonal, HatchStyle.Cross, HatchStyle.DashedDownwardDiagonal, HatchStyle.DashedHorizontal, HatchStyle.DashedUpwardDiagonal, HatchStyle.DashedVertical,
HatchStyle.DiagonalBrick, HatchStyle.DiagonalCross, HatchStyle.Divot, HatchStyle.DottedDiamond, HatchStyle.DottedGrid, HatchStyle.ForwardDiagonal, HatchStyle.Horizontal,
HatchStyle.HorizontalBrick, HatchStyle.LargeCheckerBoard, HatchStyle.LargeConfetti, HatchStyle.LargeGrid, HatchStyle.LightDownwardDiagonal, HatchStyle.LightHorizontal
};
////create rectangular area
RectangleF oRectangleF = new RectangleF(0, 0, 300, 300);
objBrush = new HatchBrush(aHatchStyles[objRandom.Next(aHatchStyles.Length - 3)], Color.FromArgb((objRandom.Next(100, 255)), (objRandom.Next(100, 255)), (objRandom.Next(100, 255))), Color.White);
objGraphics.FillRectangle(objBrush, oRectangleF);
//Generate the image for captcha
string captchaText = string.Format("{0:X}", objRandom.Next(1000000, 9999999));
//add the captcha value in session
Session["CaptchaVerify"] = captchaText;
Font objFont = new Font("Courier New", 15, FontStyle.Bold);
//Draw the image for captcha
objGraphics.DrawString(captchaText, objFont, Brushes.Black, 20, 20);
// objBitmap.Save(HttpContext.Current.Response.OutputStream, ImageFormat.Gif);
byte[] _bytes;
using (MemoryStream ms = new MemoryStream())
{
objBitmap.Save(ms, ImageFormat.Bmp);
_bytes = ms.ToArray();
}
imgcaptcha.ImageUrl = "data:image;base64," + Convert.ToBase64String(_bytes);
ImageCapchaSubmit.ImageUrl = "data:image;base64," + Convert.ToBase64String(_bytes);
}
catch (Exception)
{
}
}