I have huge images (1.800MP # 8bit or 16bit), all grayscale, no alpha, transparency or other stuff.
They may come as png, tiff, bmp, or even jpeg, so I need an image library to handle the reading, decompression and stuff.
After this, I just want to get an array with the grayscale pixel values out - preferrably 2d, but 1d is also alright. It also may be ushort all the time, even for the 8bit images.
I tried using the buid-int BitmapImage of C# - no luck, just throws exceptions for images this large.
Any other libraries that can give me the grayscale values, without hassle?
It will be faster if you use simple FileReader to read the content and generate your own array rather then looking for a library.
Related
I m new in image processing field. I have worked with bmp images but currently i have a problem at hand which needs image to be converted into YCbCr color space before further processing. I have read about YCbCr and conversion process but the problem is i have no idea how i will store the YCbCr data in image format and which image format will support it.
i mean in bmp images rgb components are stored in bgr format, bytes should be multiples of 4 etc, but what about YCbCr? how they are represented?
i m sorry if this sounds very lame. I googled it a little but the thing is i don't think i m going in right direction. Actually this is for my final project and i m running out of time.
Update: actually there is no need to store it in some image container although tiff and jpeg can be used. i get around it by just converting rgb to YCbCr processing it and then converting it back to rgb pixel by pixel.
Both the formats only need three bytes for each pixel. So, as long as you store your pixels in some uncompressed format such as ppm, you do not need to bother about the conversion. When you are writing, put the Y into R, Cb int G and Cr into the blue bytes respectively. When you read in the values, it is up to to your program to interpret them - the default interpretation of most image processing programs is to treat them as RGB, but you can tell it to read them in as YCbCr
If you choose to store it in some compressed format such as jpeg, the values that you read back might not be the same as the ones that you store, but the decision depends on the accuracy that you need.
I need to create a huge image (aprox 24000 x 22000) with PixelFormat.Format24bppRgb encoding. I know it will barely impossible to open it...
What I'm trying to do is this:
Bitmap final = new Bitmap(width, height, PixelFormat.Format24bppRgb);
As expected, an exception is thrown as I can't handle a 11GB file in memory easy that way.
But I had an idea: could I write the file as I'm generating it? So, instead of working on RAM, I would be working on the HD.
Just to better explain: I have about 13K tiles and I plan to stitch it together in this stupidly humongous file. As I can iterate them in a give order, I thing I could write it down directly to the memory using unsafe code.
Any suggestions?
ImageMagick's Large Image Support (tera-pixel) can help you put the image together once you have the tiles that compose it. You can either use use the command line and issue commands to it using this wrapper or use this ImageMagick.NET as an API.
You could write it in a non-compressed format like BMP. BMP saves raw color bytes in rows. So you would load first row of tiles, read their separate pixel rows and write it as composite single row in output image. This way, you can have open only few tiles and imediately write down the output image.
But I don't know how to write it as compressed image, like JPG or PNG. But I'm sure some specialised software exists for that.
Depending on what you intend to do with this image upon completion, I would suggest dividing it into 4 and working with it that way. I have worked with 10,000 x 10,000 pixels without the OOM exception being thrown.
Hi there I am looking to create a image dynamically from an array[500][500] (500x500pixel)
Each array item has the pixel color data,
Does anyone know which .NET library/interface would be best for this? Could point me in right direction? I need to create/save the file.
Also, The image is a composite of the data from many images, I am wondering if it is possible to use various formats, or if I need to first convert the small images into one format,
Also which image format is best to use (the most compatible?) JPG/PNG24? (for web)
Thanks for your input!
if you can use unsafe code in your website (in other words, your code runs under full trust), just use the Bitmap class, and use the LockBits method, then you can use pointers just like in C++ to access the pixels (tip: create a Pixel struct to hold RGB values). You will see GetPixel and SetPixel methods, DO NOT EVER use them. The performance is terrible, more than 100 times slower than using pointers. Just go with BitmapData.Scan0.ToPointer() and then iterate with for.
You could use the System.Drawing.Bitmap class.
If you are able to use unsafe code, construct the bitmap using pointers and BitmapData rather than SetPixel
var bitmap = new Bitmap(500, 500);
// Update the pixels with values in you array...
bitmap.Save("myfilename.jpg", ImageFormat.Jpeg);
The format depends on what you need (for example png can support transaprency, jpg does not).
You could start wich System.Drawing.Bitmap .
i was already able to convert a BMP image into binary memory stream but im confused with detecting LSB in pixel values..
I have the byte[] stream as '10101011101010101010010' ... .. ..
First is there a way that i can filter this binary stream to pixel values and detect LSB ?
If you want to read / write the Least Significant Byte to use the bitmap to hide information you will need to load the bmp data into an image, then access the pixel-data using GetPixel(). The BMP File itself might use RLL or some other compression so you cannot access the pixel data directly.
For detecting LSB in an image, it largely depends on the algorithm used, some are harder to detect as others. Do you have the description of the LSB-variant that might be in that image?
I am loading a JPG image from hard disk into a byte[]. Is there a way to resize the image (reduce resolution) without the need to put it in a Bitmap object?
thanks
There are always ways but whether they are better... a JPG is a compressed image format which means that to do any image manipulation on it you need something to interpret that data. The bimap object will do this for you but if you want to go another route you'll need to look into understanding the jpeg spec, creating some kind of parser, etc. It might be that there are shortcuts that can be used without needing to do full intepretation of the original jpg but I think it would be a bad idea.
Oh, and not to forget there are different file formats for JPG apparently (JFIF and EXIF) that you will ened to understand...
I'd think very hard before avoiding objects that are specifically designed for the sort of thing you are trying to do.
A .jpeg file is just a bag o' bytes without a JPEG decoder. There's one built into the Bitmap class, it does a fine job decoding .jpeg files. The result is a Bitmap object, you can't get around that.
And it supports resizing through the Graphics class as well as the Bitmap(Image, Size) constructor. But yes, making a .jpeg image smaller often produces a file that's larger. That's an unavoidable side-effect of Graphics.Interpolation mode. It tries to improve the appearance of the reduced image by running the pixels through a filter. The Bicubic filter does an excellent job of it.
Looks great to the human eye, doesn't look so great to the JPEG encoder. The filter produces interpolated pixel colors, designed to avoid making image details disappear completely when the size is reduced. These blended pixel values however make it harder on the encoder to compress the image, thus producing a larger file.
You can tinker with Graphics.InterpolationMode and select a lower quality filter. Produces a poorer image, but easier to compress. I doubt you'll appreciate the result though.
Here's what I'm doing.
And no, I don't think you can resize an image without first processing it in-memory (i.e. in a Bitmap of some kind).
Decent quality resizing involves using an interpolation/extrapolation algorithm; it can't just be "pick out every n pixels", unless you can settle with nearest neighbor.
Here's some explanation: http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
protected virtual byte[] Resize(byte[] data, int width, int height) {
var inStream = new MemoryStream(data);
var outStream = new MemoryStream();
var bmp = System.Drawing.Bitmap.FromStream(inStream);
var th = bmp.GetThumbnailImage(width, height, null, IntPtr.Zero);
th.Save(outStream, System.Drawing.Imaging.ImageFormat.Jpeg);
return outStream.ToArray(); }