Large Image in .net - c#

I want to create large image by C#. (i have some photos with large size (4800 * 4800). i want to merge these photos.)
I use Bitmap but don't support. (Error : Invalid Parameter)

Some code would be useful ...
... However, to hazard an educated guess, I suspect you're trying to create an instance of Bitmap with either Width or Height (or both) greater than 2^15.
Essentially, you can't - the .NET bitmap classes have a limitation on how big an image they can handle. Your original 4800 pixel square images won't be a problem, but going over 32,767 pixels will be.

you might like to check AForge.NET, it has a large image processor built in, and it's open source.

Related

Fast way to convert large vectorial images to binary matrix

I have complex vectorial images I need to convert to binary matrix (a kind of rasterizing) with high precision, using necessarily c#. Currently I'm doing it by painting vectorial images in a bitmap and reading the internal bitmap array. Then I convert this array in a binary matrix where 1 indicates that the corresponding pixel is of a specific color, and 0 when is not. As I access the internal bitmap array directly, that's fast and allows using Parallel.For
The problem is that I need to obtain very high definition matrixes of the images (50000x25000 or more). Therefore I have to paint each vectorial image dividing it in several parts, as a bitmap of this size is not supported.
As I have a lot of images to convert, it is very slow.
I'm looking for a fast way of doing that without loosing precision (ideally even increasing it). And I need to integrate this feature in a c# application.
I finally used Gdal rasterize tool, passing polygons as shapefiles, and it works quite well and fast.

Image brightness for big images c#

I use this link to add my program the capability to adjust the brightness of the image. This code is ok but it takes time to adjust the brightness(Image file size 1.8mb). When I try the lower quality image it instantly adjusts the image(Image file size 100KB). Is there any efficient way to adjust the brightness of the image.
The code seems to use GetPixel and SetPixel on regular Bitmaps. This is a bad idea because it is so slow.
To manipulate a single pixel of a Bitmap it must be locked (which Get/SetPixel do behind the scenes) and doing it on a pixel by pixel basis means that for a 1000x1000 sized image a million locking/unlocking operations must be performed. This creates an enormous overhead.
Method one
One way to avoid this is to lock the whole bitmap with the LockBits function. Now we can loop over the pixels and modify them.
Two notes about this method:
What we now access are the raw bytes of each pixel, that is each channel separately: either BGR or BGRA, depending on the pixel format. This means that the channels are physically reversed from the usual RGB/ARGB format of the Color methods.
To loop over the physical bitmap pixel rows we also need to add some stride to each row, which pads the rows to a multiple of 4 bytes. Also see here
For some examples you may want to browse over some of these posts. Note especially this one which uses a delegate to allow for flexible operations!
(Note that several of the posts use 2 or even 3 locked bitmaps because they aim at combining images..)
Method two
Another way to get around the overhead of locking pixels one by one are ready-made bitmap classes that help by locking themselves as a whole. Here and here are examples I didn't try myself.
Method three
Finally there is a very elegant method for image manipulation, which is both rather simple and really fast; also professionally crafted for best results: You can set up a ColorMatrix.
It will let you change brightness, gamma, hues and then some. Here is a very nice introduction.
The only drawback is, that is limited to some fixed operations, so you can't create custom filters for other fancy stuff, like photoshop-type layer modes or others, especially those that need to process neighbouring pixels e.g. for blurring..
But if all you want is changing brightness, this is what I would recommend!

Best way to get image dimensions using ImageResizer

I am switching an existing MVC 4 website from home-cooked user file uploads to resizing files with ImageResizer as they are uploaded.
I see in the documentation that I should not use System.Drawing, but I can't figure out any other way of grabbing the image dimensions.
It does not matter if the dimensions are from the original image or a resized image, since I am preserving aspect ratio and merely need to determine if an image is landscape or portrait.
I am adding the code here that I refer to in my comment responding to #Nathanael's answer.
ImageJob ij = new ImageJob(file, requestedImageInfo: null);
int ? y = ij.SourceWidth;
int ? z = ij.SourceHeight;
If you can store the image dimensions during upload (from ImageJob.SourceWidth/Height or LoadImageInfo), that is best, as reading image dimensions from a file involves lots of I/O.
If not, ImageResizer offers the IDictionary LoadImageInfo(object source, IEnumerable requestedInfo) method to do so after the fact. Just keep in mind, it does involve reading from disk, and you don't want to call this lots of times in a single HTTP request. Put those numbers in the database.
You can always calculate the final size of an image via ImageBuilder.GetFinalSize(originalSize, instructions). This, on the other hand, is very fast, as it involves no I/O, just math.

How to read and modify the colorspace of an image in c#

I'm loading a Bitmap from a jpg file. If the image is not 24bit RGB, I'd like to convert it. The conversion should be fairly fast. The images I'm loading are up to huge (9000*9000 pixel with a compressed size of 40-50MB). How can this be done?
Btw: I don't want to use any external libraries if possible. But if you know of an open source utility class performing the most common imaging tasks, I'd be happy to hear about it. Thanks in advance.
The jpeg should start with 0xFF 0xD8. After that you will find various fields in the format:
Field identifier 2 bytes
Field length, excluding field identifier. 2 bytes.
Variable data.
Parse through the fields. The identifier you will be looking for is 0xFF 0xC0. This is called SOF0, and contains height, width, bit depth, etc. 0xFF 0xC0 will be followed by two bytes for the field length. Immediately following that will be a single byte showing the bit depth, which will usually be 8. Then there will be two bytes for height, two for width, and a single byte for the number of components; this will usually be 1 (for greyscale) or 3. (for color)
This isn't something I've tried myself, but I think you might need to acccess the picture's EXIF information as a start.
Check out Scott Hanselman's blog-entry on accessing EXIF information from pictures.
Standard .NET System.Drawing namespace should have all that you need,
but it probably won't be very efficient. It'll load the whole thing into RAM, uncompress it, convert it (probably by making a copy) and then re-compress and save it. If you aim for high performance, I'm afraid you might need to look into C/C++ libraries and make .NET wrappers for them.
As far as I know jpg is always 24 bpp. The only thing that could change would be that it's CMY(K?) rather then RGB. That information would be stored in the header. Unfortunately I don't have any means of creating a CMYK image to test whether loading into a Bitmap will convert it automatically.
The following line will read the file into memory:
Bitmap image = Image.FromFile(fileName);
image.PixelFormat will tell you the image format. However, I can't test what the file load does with files other than 24bpp RGB jpgs. I can only recommend that you try it out.

Read subsection of Bitmap from disk in C#

I'm writing some map software for my smartphone and have hit a problem whereby I don't want to load all of the (large) image files into memory when only a portion will be displayed.
Is there a way to read only a subsection (the viewable portion) of a big image given that you know the x and y offsets and width? I know it's probably possibly to do it by reading the file a byte at a time but I'm not sure how to do this.
Thank you,
Nico
It's going to depend at least in part on what format(s) your images are saved in. If you have raw image files or bitmaps, it may be possible, but if your data is compressed in any manner, such as JPEG or PNG, it's going to be a lot more difficult to read just a subsection.
If you truly don't want to ever load the full data into memory, you'll have to write your own IO routine that reads the file. For anything more complex than BMP, your decompression algorithm could get complicated.
If it's a BMP file, it shouldn't be that hard.
First you read the header from the file, if I recall correctly it's 44 bytes, but you can find that out from searching the web for a specification.
The header contains information like how many bytes there are per pixel, total width and height, how many bytes per scan line. Normally the bitmap is stored upside down, so you would calculate where in the file the first pixel of the bottom line was and skip to that location. Then you read the pixels you want from that line and skip to the correct pixel on the next line.
The FileStream class has what you need; a Read method for reading and a Seek method to skip to a given position.
Couldn't you cut the image up into sections beforehand?
Splitting it into many 256x256 pixel images means you'd only have to load a couple of them and stitch them back together on the viewable canvas. To name one implementation - google maps uses this technique.
This is something I have done with bitmaps...
public BitmapCropBitmap(BitMap fullBitmap, Rectangle rectangle)
{
return proBitmap.clone(fullBitmap, rectangle, fullBitmap.PixelFormat);
}

Categories

Resources