I need to create a figure (square) where for each client registered in the system, I put a pixel in a chosen location of the square by the client. I have this example . I need a hint in C # on how to get started.This is only exemple to start.
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 RandomPixelImage
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
int width = 640, height = 320;
//bitmap
Bitmap bmp = new Bitmap(width, height);
//random number
Random rand = new Random();
//create random pixels
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
//generate random ARGB value
int a = rand.Next(256);
int r = rand.Next(256);
int g = rand.Next(256);
int b = rand.Next(256);
//set ARGB value
bmp.SetPixel(x, y, Color.FromArgb(a, r, g, b));
}
}
//load bmp in picturebox1
pictureBox1.Image = bmp;
//save (write) random pixel image
bmp.Save("D:\\Image\\RandomImage.png");
}
}
}
Since you have already made a Bitmap, all you need to do is assign that to PictureBox control:
First add a PictureBox control to your form, and then add this code to get your image onto it.
pictureBox.Image = bmp;
As your example shows, you can use Bitmap.SetPixel() to alter single pixels.
Related
using ImageMagick;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
namespace Weather
{
public class RadarPixels
{
public RadarPixels(string imageToChange, string folderToSave)
{
ConvertRadarImages(imageToChange, folderToSave);
}
public static Bitmap Create32bpp(System.Drawing.Image image, Size size)
{
Bitmap bmp = new Bitmap(size.Width, size.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(bmp))
{
gr.Clear(Color.White);
gr.DrawImage(image, new Rectangle(0, 0, bmp.Width, bmp.Height));
}
return bmp;
}
public void ConvertRadarImages(string imageToChange, string folderToSave)
{
var image1 = Create32bpp(System.Drawing.Image.FromFile(imageToChange), new Size(512, 512));
var image2 = new Bitmap(Properties.Resources.radar_without_clouds);
image1.SetResolution(96, 96);
image2.SetResolution(96, 96);
int tolerance = 64;
var img1 = new LockBitmap(image1);
var img2 = new LockBitmap(image2);
img1.LockBits();
img2.LockBits();
for (int x = 0; x < image1.Width; x++)
{
for (int y = 0; y < image1.Height; y++)
{
Color pixelColor = img1.GetPixel(x, y);
// just average R, G, and B values to get gray. Then invert by 255.
int invertedGrayValue = 255 - (int)((pixelColor.R + pixelColor.G + pixelColor.B) / 3);
if (invertedGrayValue > tolerance) { invertedGrayValue = 255; }
// this keeps the original pixel color but sets the alpha value
img1.SetPixel(x, y, Color.FromArgb(invertedGrayValue, pixelColor));
}
}
img1.UnlockBits();
img2.UnlockBits();
using (Graphics g = Graphics.FromImage(image2))
{
g.CompositingMode = CompositingMode.SourceOver;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(image1, new Point(0, 0));
}
string fileToSave = Path.GetFileName(imageToChange);
image2.Save(Path.Combine(folderToSave, fileToSave), ImageFormat.Png);
}
}
}
in form1
radarPixels = new RadarPixels(savedFile, Path.GetDirectoryName(savedFile));
i'm getting exception error on the line :
image2.Save(Path.Combine(folderToSave, fileToSave), ImageFormat.Png);
System.Runtime.InteropServices.ExternalException: 'A generic error
occurred in GDI+.'
folderToSAve contains : "E:\Downloaded Images\Radar\Tuesday 02.07.2023 at 23.09 PM"
fileToSave contains : "2023_02_07_23_05.png"
the current image file on the hard disk is : 2023_02_07_22_55.png
what i want to do is that after manipulating on the image 2023_02_07_22_55.png to save the changes made overwriting the same file name : 2023_02_07_22_55.png
but getting this exception error.
tried :
image2.Save(Path.Combine(folderToSave, fileToSave), ImageFormat.Png);
but getting the exception error.
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 Read_Drawn
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Bitmap image = new Bitmap(#"d:\drawplane1.jpg");
Bitmap mynewimage = new Bitmap(image.Width, image.Height);
for (int i = 0; i < image.Height; i++)
{
for (int j = 0; j < image.Width; j++)
{
Color c = image.GetPixel(j, i);
if (c.R == 0 && c.G == 0 && c.B == 0)
{
mynewimage.SetPixel(j, i, Color.Black);
}
}
}
pictureBox1.Image = mynewimage;
}
}
}
If I just assign the image to the pictureBox1 it will show png fine in the pictureBox1 but I want now to show only the black pixels I mean to show only the draw without the white background but it's showing only few if at all black pixels in the pictureBox1.
If I'm doing :
if (c.R == 0 && c.G == 0 && c.B == 0)
{
mynewimage.SetPixel(j, i,c);
}
else
{
mynewimage.SetPixel(j, i, c);
}
Then it will draw a copy of the original file image but I want only the black draw without the white background.
Update :
This is the original image :
I want to get only the drawn airplane without the white background and without any other stuff.
This is the script now :
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 Read_Drawn_Sketches
{
public partial class Form1 : Form
{
private Bitmap bmp;
private Bitmap image;
public Form1()
{
InitializeComponent();
trackBar1.Minimum = 0;
trackBar1.Maximum = 50;
image = new Bitmap(#"d:\drawplane1.jpg");
bmp = (CreateNonIndexedImage(image));
ConvertImageToBlackAndWhite(bmp);
GetImagePixels();
pictureBox1.Image = bmp;
}
private void GetImagePixels()
{
for (int i = 0; i < image.Height; i++)
{
for (int j = 0; j < image.Width; j++)
{
Color c = image.GetPixel(j, i);
if (c.R == 255 && c.G == 255 && c.B == 255) // white is an equal mix of every colour
{
bmp.SetPixel(j, i, Color.Transparent);
}
}
}
}
private void ConvertImageToBlackAndWhite(Bitmap SourceImage)
{
using (Graphics gr = Graphics.FromImage(SourceImage)) // SourceImage is a Bitmap object
{
var gray_matrix = new float[][] {
new float[] { 0.299f, 0.299f, 0.299f, 0, 0 },
new float[] { 0.587f, 0.587f, 0.587f, 0, 0 },
new float[] { 0.114f, 0.114f, 0.114f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
};
var ia = new System.Drawing.Imaging.ImageAttributes();
ia.SetColorMatrix(new System.Drawing.Imaging.ColorMatrix(gray_matrix));
ia.SetThreshold(trackBar1.Value); // Change this threshold as needed
var rc = new Rectangle(0, 0, SourceImage.Width, SourceImage.Height);
gr.DrawImage(SourceImage, rc, 0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel, ia);
}
}
public Bitmap CreateNonIndexedImage(Image src)
{
Bitmap newBmp = new Bitmap(src.Width, src.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics gfx = Graphics.FromImage(newBmp))
{
gfx.DrawImage(src, 0, 0);
}
return newBmp;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
bmp = (CreateNonIndexedImage(image));
ConvertImageToBlackAndWhite(bmp);
pictureBox1.Image = bmp;
}
}
}
When running the application I see in the pictureBox :
It looks like transparent but the airplane and other things that was in black are in white. I want it to be transparent but to keep only the black drawn.
Now if I'm moving the trackBar by one to the right I'm getting this :
It's ion black but the background is now not transparent :
Now I moved the trackbar a bit more to the right now you can see more black stuff around the airplane :
And last I moved the trackbar to the far end to the right and this is I think how it should be the airplane but the background should be transparent and not white:
The main goal is to take the image source from the hard disk and get only the airplane in black with transparent background and I prefer to make it in the code without an external tool or in some website even if it's more slower.
This is a link for the image file : https://easyupload.io/3l01vf
I'm not sure, but if you want to remove whiteback ground and make it transparent, you want to look for color = 255. So that would be:
public Form1()
{
InitializeComponent();
Bitmap image = new Bitmap(#"d:\drawplane1.jpg");
Bitmap mynewimage = new Bitmap(image.Width, image.Height);
for (int i = 0; i < image.Height; i++)
{
for (int j = 0; j < image.Width; j++)
{
Color c = image.GetPixel(j, i);
if (c.R == 255 && c.G == 255 && c.B == 255) // white is an equal mix of every colour
{
mynewimage.SetPixel(j, i, Color.Transparent);
}
}
}
pictureBox1.Image = mynewimage;
Note: this only works for complete white. If your background has some slightly different shades of white, you may need to use a range instead, such as 200 < c.R && c.R < 255 &&.. but I don't know how your image looks like so you'll have to play with the numbers yourself.
All that said, if your goal is to just remove the image background, you can use a free online background image remover. I normally just do that, works very quickly.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Util;
using Emgu.CV.Structure;
namespace DCTTransform
{
public partial class Form1 : Form
{
Image<Bgr, Byte> img;
Image<Ycc, Byte> imgYcc;
Bitmap bmp;
public Form1()
{
InitializeComponent();
}
private void btBrowse_Click(object sender, EventArgs e)
{
OpenFileDialog od = new OpenFileDialog();
if (od.ShowDialog() == DialogResult.OK)
{
img = new Image<Bgr, byte>(od.FileName);
pcCitra.Image = img.ToBitmap();
label1.Text = img.Width.ToString();
}
}
//Split citra
public List<Image> subBlok(Image img, int blokX, int blokY)
{
List<Image> res = new List<Image>();
int pembagiLebar = img.Width / blokX;
int pembagiTinggi = img.Height / blokY;
for (int i = 0; i < blokX; i++)//baris
{
for (int j = 0; j < blokY; j++)//kolom
{
Bitmap bmp = new Bitmap(img.Width / pembagiLebar, img.Height / pembagiTinggi);
//Bitmap bmp = new Bitmap(img.Width, img.Height);
Graphics grp = Graphics.FromImage(bmp);
grp.DrawImage(img, new Rectangle(0,0 , bmp.Width, bmp.Height), new Rectangle(j * bmp.Width, i * bmp.Height, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
res.Add(bmp);
}
}
return res;
}
private void btTransform_Click(object sender, EventArgs e)
{
//SplitImage
List<Image> imgs = subBlok(pcCitra.Image, 8, 8);
pbDCT.Image = imgs[0];
}
}
}
I have made this code to divide an image into 8 x 8 pixels, but the result shows just 1 block (8 x 8) in the upper left corner.
All I want is like this:
|xxxx|xxxx|xxxx|xxxx|.......... until the same width to original image.
Can you help me with this?
If you want to divide your source image into multiple 8x8 tiles, then your transform function's loops are incorrect. If you want to divide your source image into 64 tiles then they are correct, but DCT doesn't usually work with a static set of 64 images. I am unclear on which one you want, but I fixed it up for multiple 8x8 images here:
List<Image> res = new List<Image>();
int pembagiLebar = (int)Math.Ceil((float)img.Width / (float)blokX);
int pembagiTinggi = (int)Math.Ceil((float)img.Height / (float)blokY);
for (int i = 0; i < pembagiLebar ; i++)//baris
{
for (int j = 0; j < pembagiTinggi ; j++)//kolom
{
Bitmap bmp = new Bitmap(blokX, blokY);
using (Graphics grp = Graphics.FromImage(bmp)) {
grp.DrawImage(img, 0, 0, new Rectangle(i * blokX, j * blokY, blokX, blokY), GraphicsUnit.Pixel);
}
res.Add(bmp);
}
}
return res;
The boundary condition on the right and bottom edge is also annoying to take care of (which I have not here), since the source image dimensions may not be multiples of 8.
There are a couple of approach you can do. The easiest way for processing is to store your image values in rows with lengths that are multiples of 8. Pad the data out. Do the same for then do the same for the number of rows.
Then the blocks are (assuming grayscale)
X = starting point
v0 = X
v1 = X + 1
v2 = X + 2
. . .
v8 = X + row length
v9 = X + row length + 1
v10 = X + row length + 2
. . .
v63 = x = 7 * row length + 7
To move to the next block in the row X = X + 8. When you reach the end of the row
X = X + 8 * row length
Keep in mind that your output elements need to be twice the size of the input. If your image data is 8 bits, your DCT output will need to be 16 bits for an integer representation (or a floating point value).
If you cannot pad the data, your best bet is to copy the values to a 64 entry array. You'd do a loop similar to the above but, any time you would need to access a value beyond the width or height of the image, insert a 0 into the temporary array.
Please imagine I have a very simple chequerboard image.
Here I represent the image with letters as pixels: black pixel 'B', white pixel 'W'
Here is the starting 2x2 pixel image:
BW
WB
I want to resize the image, lets say by scale of 2x to give me :
BBWW
BBWW
WWBB
WWBB
or scale 4x
BBBBWWWW
BBBBWWWW
WWWWBBBB
WWWWBBBB
So that the pixel colours are not dithered in any way at all.
I have tried this in C# but the image is a mess, all dithered, I need to learn how to do this without dithering/color change.
Here is my code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
namespace PageTwine
{
public partial class RandonGiff : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// create 2x2 chequerboard:
Bitmap oBitmap = new Bitmap(2, 2);
Graphics oGraphic = Graphics.FromImage(oBitmap);
// color black pixels (i think the default is black but this helps to explain)
SolidBrush oBrush = new SolidBrush(Color.FromArgb(255, 255, 255));
oGraphic.FillRectangle(oBrush, 0, 0, 1, 1);
oGraphic.FillRectangle(oBrush, 1, 1, 1, 1);
//color white pixels
oBrush = new SolidBrush(Color.FromArgb(0, 0, 0));
oGraphic.FillRectangle(oBrush, 0, 1, 1, 1);
oGraphic.FillRectangle(oBrush, 1, 0, 1, 1);
// expand to 4x4
Bitmap result = new Bitmap(4, 4);
using (Graphics graphics = Graphics.FromImage(result))
{
// I don't know what these settings should be :
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
//draw the image into the target bitmap
graphics.DrawImage(oBitmap, 0, 0, result.Width, result.Height);
}
//send image directly to the browser
Response.ContentType = "image/gif";
result.Save(Response.OutputStream, ImageFormat.Gif);
}
}
}
The result is a dithered image, but I need a clean crisp chequerboard effect.
Please can you help me.
EDIT:07/02/12
Thanks for the suggestions so far but I am still searching without finding a solution.
I have created a demo page so you can see the results for yourself.
The URL for the demo is :
http://www.leansoftware.net/servicedesk/publicadhoc/randomgif.aspx?columns=3&rows=3
The demo will create a chequerboard with initial columns x rows as pixels, then enlarge to a gif image 300x300 px.
You will see that colours are distorted/bitty - this I am trying to solve.
Here is the source code for the demo:
using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Linq;
public partial class RandomGif : System.Web.UI.Page
{
public class Coordinates
{
public int x { get; set; }
public int y { get; set; }
}
static Random rand = new Random();
protected void Page_Load(object sender, EventArgs e)
{
// Output type gif
int iwidth;
int iheight;
int bits;
Response.ContentType = "image/gif";
// Get parameters
if (Request.QueryString["count"] != null)
{
bits = Convert.ToInt32(Request.QueryString["count"]);
int square = Convert.ToInt32(Math.Ceiling(Math.Sqrt(bits + Math.Floor(bits / 4.0))));
iwidth = square;
iheight = square;
bits = (square * square)-1;
}
else
if (Request.QueryString["rows"] != null && Request.QueryString["columns"] != null)
{
iwidth = Convert.ToInt32(Request.QueryString["columns"]);
iheight = Convert.ToInt32(Request.QueryString["rows"]);
bits = (iwidth * iheight);
}
else {
return;
}
if (bits > 1000){
Response.Write("Please specify a grid <= 1000 pixels");
return;
}
int plotCount = 0;
//web safe colors : 00, 33, 66, 99, CC, FF;
List<int> webSafeColor = new List<int>();
webSafeColor.Add(0); //00
webSafeColor.Add(51);//33
webSafeColor.Add(102);//66
webSafeColor.Add(153);//99
webSafeColor.Add(204);//CC
webSafeColor.Add(255);//FF
// Create a structure to hold all possible coordinates
var Grid = new List<Coordinates>();
for (int xi = 1; xi <= iwidth; xi++)
{
for (int yi = 1; yi <= iheight; yi++)
{
Grid.Add(new Coordinates { x = xi, y = yi });
plotCount++;
}
}
//create a new Bitmap object
Bitmap oBitmap = new Bitmap(iwidth, iheight);
//create a new Graphics object, which will allow us to draw on our bitmap:
Graphics oGraphic = Graphics.FromImage(oBitmap);
//fill the image rectangle with n bits
for (int i = 1; i <= bits; i++)
{
//Random rand = new Random();
int row = rand.Next(Grid.Count());
// random red
int ircolor = webSafeColor[rand.Next(5)];
// random green
int igcolor = webSafeColor[rand.Next(5)];
// random blue
int ibcolor = webSafeColor[rand.Next(5)];
Color randomColor = Color.FromArgb(ircolor, igcolor, ibcolor);
SolidBrush oBrush = new SolidBrush(randomColor);
oGraphic.FillRectangle(oBrush, Grid[row].x - 1, Grid[row].y - 1, 1, 1);
// Delete this coordinate#
Grid.Remove(Grid[row]);
}
// resize image
Bitmap result = new Bitmap(300, 300);
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.AssumeLinear;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
//draw the image into the target bitmap
graphics.DrawImage(oBitmap, 0, 0, result.Width, result.Height);
}
//send image directly to the browser
Response.ContentType = "image/gif";
result.Save(Response.OutputStream, ImageFormat.Gif);
}
}
If you can suggest modifications we can try them out and see if it fixes the problem.
Thanks Richard
This is a possible duplicate of c# Draw Image (Scaled) to Graphics, does not interpolate correctly. Fixes?
You need to add:
graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
Alternately, you could use
graphics.DrawImage(oBitmap, 0, 0, result.Width * 2, result.Height * 2);
to achieve a similar effect of forcing the brush to fill without warping at the right-bottom image edges.
Update:
Adding link for creating indexed images with a custom color palette.
http://support.microsoft.com/kb/319061
Use:
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
I set up a code to randomly cover a bitmap 2 different colors, 7 out of 10 times the color would be blue, and 3 out of 10 times, the color would be green. However, when it's done it looks very un-random, like it decided to put 7 blue pixels a few times, then 3 green pixels a few times and so on.
Example:
My code is:
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;
namespace FourEx
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(canvas.Image);
System.Drawing.Imaging.BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, 800, 600), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
unsafe
{
int tempy = 0;
while (tempy < 600)
{
byte* row = (byte*)bmpdata.Scan0 + (tempy * bmpdata.Stride);
for (int x = 0; x <= 800; x++)
{
Random rand = new Random();
if (rand.Next(1,10) <= 7)
{
row[x * 4] = 255;
}
else
{
row[(x * 4) + 1] = 255;
}
}
tempy++;
}
}
bmp.UnlockBits(bmpdata);
canvas.Image = bmp;
}
}
}
If you need an additional information, let me know.
move this line:
Random rand = new Random();
to the outermost scope. If you create these quickly many will get the same time seed (due to precision of the clock) and will generate the same 'random' sequence. Plus, you only really need one Random instance...
private void Form1_Load(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(canvas.Image);
System.Drawing.Imaging.BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, 800, 600), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Random rand = new Random();
unsafe
{
// ....