I have list pixels in this format
ArrayList list = new ArrayList();
list.add(Red);
list.add(Blue);
list.add(Green);
I have many values like this. I want to convert the array list to image.. Tried a lot but haven't found any proper material.
EDIT: This may helps:
List<byte> pic = new List<byte>();
for (int j = 0; j < headdata.Count; j++)
{
if(headdata.ElementAt(j).getHead() == i)
{
pic.Add((byte)headdata.ElementAt(j).getRed());
pic.Add((byte)headdata.ElementAt(j).getGreen());
pic.Add((byte)headdata.ElementAt(j).getBlue());
}
}
Images are stored in the form of a matrix of numbers in a computer where these numbers are known as pixel values. These pixel values represent the intensity of each pixel. 0 represents black and 255 represents white.
Pixel data describe a color image with a single sample per pixel (single image plane). The pixel value is used as an index into each of the Red, Blue, and Green Palette Color Lookup Tables (0028,1101-1103&1201-1203). This value may be used only when Samples per Pixel (0028,0002) has a value of 1.
Typically, the pixels are stored in computer memory as a raster image or raster map, a two-dimensional array of small integers. These values are often transmitted or stored in a compressed form.
Update
I thought I would improve this answer for future reference.
It can be much more convenient (and performant) to store the pixels as an array of unsigned 32-bit integers (a C# uint
). This allows the 4 channels of each pixel (alpha, red, green, and blue) to be set in one go. If you are not interested in using the alpha channel (for transparency), see the comment regarding pixel formats in the code snippet below.
The way you would represent colours is now as 32-bit numbers such as 0xff0000
, which you may recognise as being similar to CSS hex colour values.
// Image dimensions.
var width = 640;
var height = 480;
// Array to contain pixel data, with each element representing one pixel.
var pixelBuffer = new uint[width * height];
// When creating the bitmap, the operating system needs to be told the memory
// address of the pixel data array created above. This memory address can be
// found using a pinned GC handle, which also tells the GC (garbage collector)
// that it cannot move the array in memory after this point (as that would
// change the memory address).
//
// Note that the handle prevents the GC from freeing the object automatically,
// so remember to call the handle's `Free` method once finished (see below).
var pixelBufferHandle = GCHandle.Alloc(pixelBuffer, GCHandleType.Pinned);
// Create the bitmap using a constructor that takes a pointer to the array of
// pixel data:
//
// The `width` and `height` parameters are the image dimensions in pixels.
// These should match the values used above.
//
// The `stride` parameter specifies the number of _bytes_ required for each row
// of image data. Calculate this by multiplying the image's width by the number
// of bytes per pixel (here that's `sizeof(uint)`).
//
// The `format` parameter specifies how the colour data of each pixel is stored
// in the pixel data array:
// - For 32-bit RGB colour, use `Format32bppPArgb`. This signifies that the
// alpha channel is present (i.e. each pixel is 4 bytes) but should be
// ignored. Each pixel will be 100% opaque, and the alpha can be zero.
// - For 32-bit ARGB colour, use `Format32bppArgb`. Each pixel will be drawn
// opaque, semi-transparent, or fully transparent based on the alpha.
//
// The `scan0` parameter takes a pointer to the pixel data - use the GC handle
// created above to acquire the address of the array object.
var bitmap = new Bitmap(
width: width,
height: height,
stride: width * sizeof(uint),
format: PixelFormat.Format32bppPArgb,
scan0: pixelBufferHandle.AddrOfPinnedObject()
);
// At this point, the pixel data array can be freely manipulated independently
// of the bitmap. Each time the bitmap is draw, it will reflect the current
// content of the pixel data array.
// Once finished...
// Free the GC handle, allowing the GC to free the object automatically.
gchPixels.Free();
You can create functions for reading and writing pixels at specific coordinates:
uint GetPixel(int x, int y) => pixels[x + y * width];
void SetPixel(int x, int y, uint argb) => pixels[x + y * width] = argb;
As starbeamrainbowlabs pointed out:
GCHandle
, Bitmap
, and PixelFormat
are found in System.Runtime.InteropServices
, System.Drawing
, and System.Drawing.Imaging
respectively.
Original Answer Below...
There is quite a good way of doing this, but it requires that you use an array or bytes as opposed to a list.
Consider this:
// Define the width and the height of the image
int width = 100;
int height = 100;
/// Create an array of bytes consisting of the area's worth of pixels
/// with 3 bytes of data each.
byte[] pixels = new byte[width * height * 3];
/* ... Code for making the image etc. here ... */
// Create the bitmap.
// GCHandle requires System.Runtime.InteropServices
/// PixelFormat requires System.Drawing.Imaging.
Bitmap bmp = new Bitmap(width, height, width * 3, PixelFormat.Format24bppRgb,
GCHandle.Alloc(pixels, GCHandleType.Pinned).AddrOfPinnedObject());
If you want to change this to be ARGB, simply change all instances of '3' with '4', and use PixelFormat.Format32bppArgb.
As I said, this requires that you use an array as opposed to a list, but this shouldn't be too difficult as long as you know the width and height of the image. A good way of setting an individual pixel in the array is (perhaps make a method for this) :
pixels[x + y * width] = R;
pixels[x + y * width + 1] = G;
pixels[x + y * width + 2] = B;
This method is generally quite fast too, if that's at all necessary for whatever you're doing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With