Resizing an image using Magick.net - c#

I've got an image that I want to resize using Magick.net before displaying in an ASP .Net page, but when I look at the displayed image in my browser, it comes up as a broken image.
Here's what my code would look like if I wasn't resizing:
this.LogoBox.Image = _myModel.LogoImage;
Here's what my ImageMagick-using code looks like:
var logoToDisplay = new MagickImage(new Bitmap(_myModel.LogoImage));
logoToDisplay.Resize(imageWidth, imageHeight);
this.LogoBox.Image = logoToDisplay.ToBitmap();
When I take out the second ...Resize... line, nothing comes up. I can't seem to find good documentation for Magick.net, even on the CodePlex site.
Any thoughts?

When you use the ToBitmap method your image will be converted to Bmp. You probably want to use another image format, e.g. ImageFormat.Png or ImageFormat.Jpeg. Feel free to post a message here also: https://magick.codeplex.com/discussions. And can you also put up a link to the image you are trying to resize?

Related

Comparing two images using ImageMagick and C#

I want to compare two images and then generate and save an image that will show all the differences that has been found,
for example:
I am using ImageMagick: https://magick.codeplex.com/
But they don't have full documentation for C#.
I found only: http://www.imagemagick.org/Usage/compare/
This code for example show value from 0-1 that represent how similar the pictures are:
MagickImage img1 = new MagickImage(#"C:\test\Image1.jpg");
MagickImage img2 = new MagickImage(#"C:\test\Image2.jpg");
double diff = img1.Compare(img2,new ErrorMetric());
But how can I compare the images using ImageMagick and then save the result as shown in the example above and in their website?
Update:
With the help of dlemstra I wrote the following code and I generate images that suppose to show the difference as in the example above.
MagickImage img1 = new MagickImage(#"C:\test\Image1.jpg");
MagickImage img2 = new MagickImage(#"C:\test\Image2.jpg");
MagickImage img3 = new MagickImage(#"C:\test\Image3.jpg");
MagickImage img4 = new MagickImage(#"C:\test\DiffImage.jpg");
MagickImage img5 = new MagickImage(#"C:\test\DiffImage.jpg");
var imgDiff = new MagickImage();
img1.Compare(img2, new ErrorMetric(), imgDiff);
imgDiff.Write(#"C:\test\Diff4.jpg");
img1.Compare(img3, new ErrorMetric(), imgDiff);
imgDiff.Write(#"C:\test\Diff5.jpg");
img1.Compare(img4, new ErrorMetric(), imgDiff);
imgDiff.Write(#"C:\test\Diff6.jpg");
img5.Compare(img4, new ErrorMetric(), imgDiff);
imgDiff.Write(#"C:\test\Diff7.jpg");
The Strange results are: When I compare the following two images with the marked only difference:
This is the result that I get (And not as the example above from "imageMagick"
You will need to use one of the other overloads of the Compare method for this. The example below demonstrates how to do this:
using (var img1 = new MagickImage(#"C:\test\Image1.jpg"))
{
using (var img2 = new MagickImage(#"C:\test\Image2.jpg"))
{
using (var imgDiff = new MagickImage())
{
double diff = img1.Compare(img2, new ErrorMetric(), imgDiff);
imgDiff.Write(#"C:\test\Diff-Image1-Image2.jpg");
}
}
}
But when you are working with jpeg images (they are lossy) you probably also want to set the ColorFuzz on the first image:
img1.ColorFuzz = new Percentage(5); // adjust this value for your situation
This will make it so that pixels that are almost the same will also match.
Lessons Learned:
Wanted to add some important notes so others hopefully avoid the pitfalls which I ran into when testing out ImageMagick (or any compare tool) for the first time.
Beware of editing in Windows Paint in general.
Don’t edit a *.png with a transparent background in Windows paint and expect a good compare. Windows Paint doesn’t handle transparent background and the png you edited in Paint will now have a white background. The Image will look exactly the same to the naked eye but the image comparers know better.
If you have SnagIt, this is a better tool for making edits to an image when you want to put a image compare tool to the test.
Conclusion:
The code written by #dlemstra does work as expected. Just make sure that when you are testing out the first time that the second image (which you modified) didn’t get unintentionally modified by the image editor that you use. This is a general warning for when you are testing out any image compare tool for the first time to see if you want to use it or not.
Examples:
Example 1: Transparent png + Windows Paint
Downloading a transparent image, making and edit to it in Paint which unintentionally also changes background to white instead of transparent.
Just by opening, then saving the second image in Paint without making any edits to the image will cause the diff to look like this:
I couldn’t figure out what was going on until I compared with Beyond Compare:
Example 2: Complex *.jpg + Windows Paint
Windows Paint was also not good at keeping complex images identical between saves:
The big red areas were changes I had made, but the thin outlines of the roses were changes that Windows Paint made to the picture
Even when I made no changes at all and just open, saved and closed the second image in Paint (and the original image was an image which had also been saved in Paint), Paint still made undesired edits to the picture (dark red dots in image):
I then had an original image which had been saved in Paint and copied this image, opened the second image in snagIt, saved the second image in snagit, and then closed the image and compared the two images (which should have been identical). However, it seemed that snagIt made it’s own modifications to the original ‘Paint saved’ image:
Lastly, I copied the ‘Snagit saved’ image, opened this second image also in SnagIt, made an edit to the second image, saved the image in SnagIt and then closed the image. SnagIt did not make any modifications to this image and the compare showed exactly what I expected:
Lastly:
Most information you find about ImageMagick pertains to using it via the command line. You can add the Magick.Net nuget to your C# project in Visual Studio by installing it via the NuGet Package Manager

Dynamically create a picture with some texts and background image as PNG

I have the following:
A headline (text)
A tagline (text)
A background image (url to this image)
I need to set these dynamically together in an image, and then store it as a PNG file. All of this happens in a web service which sends some kind of stream back.
I would love to be able to style this with CSS, as it would be nice to add some CSS effects to the picture. If that is not possible, it is fine as well.
So far I've thought about using the Bitmap class, and then insert my things dynamically. This is definetely one way to go, but I would really prefer some more design-friendly way like CSS.
What is the prefered way to do this? Any experiences?
Check out System.Drawing.Graphics.
Bitmap bmp = new Bitmap(500, 500);
using (Graphics g = Graphics.FromImage(bmp)) {
g.Clear(Color.Black);
// ...
}
You can then call Image.Save (bmp.Save(...)) to save the image to disk or even to a MemoryStream.
The answer from Angelo Geels will let you create a dynamic bitmap in your code. If you need more flexibility then you might want to use the SVG format instead, and possibly render it as a PNG file if you absolutely need that format.
SVG is an XML based image format where you define a viewport and shapes that should be drawn into it. It is vector based so the images can be scaled up and down to any size.
It should be quite easy to write an ASP.Net Http Handler that outputs an SVG xml file with some dynamic content based on user input. An even easier option would be to serve static SVG files that your designers create, but then you might as well serve static PNG files.
If you want to use the SVG approach for its flexibility but still need to output PNG's then you can use the SVG.Net library to read the SVG file and then use the SvgDocument.Draw method to draw the image to a Bitmap object that can then be written out as a PNG file.

C# Image Deskew

Has anyone seen any image deskew algorithms in c#? I have found:
http://www.codeproject.com/KB/graphics/Deskew_an_Image.aspx
but unfortunately, it doesn't do very much for images without text. I am specifically trying to auto deskew an image of a book with solid edges, but minimal text.
Has anyone seen anything that may be able to do this?
The basic algorithm is to use a Hough transform to find the lines and then try to make most of the lines horizontal. Here's some basic code http://www.sydlogan.com/deskew.html
For your situation, you might want to target the transform at a piece of the image you know might have the best information. For example if there's a page border -- I'd need to see an example to give better advice.
Disclaimer, I work at Atalasoft.
Our DotImage toolkit has it built in for .NET and is runtime royalty-free for desktop applications. Code would be:
AtalaImage img = new AtalaImage("imagefile.tif");
AutoDeskewCommand cmd = new AutoDeskewCommand();
AtalaImage resultImage = cmd.Apply(img).Image;
resultImage.Save("result.tif", new TiffEncoder(), null);
Or something similar for multipage or other types of images.
We show how to integrate it with our viewer control in this video (at 1:14)
http://www.atalasoft.com/products/dotimage/tutorials/capture/lesson4.aspx
The videos are part of a series of building a document scanning application:
http://www.atalasoft.com/products/dotimage/tutorials/capture/lesson1.aspx
http://www.atalasoft.com/products/dotimage/tutorials/capture/lesson2.aspx
http://www.atalasoft.com/products/dotimage/tutorials/capture/lesson3.aspx

Resizing an image after loading it from the database using asp.net, C#

I have a user-uploaded image pulled from the database that I am resizing smaller to display on a web page that I intend to print. I thought about saving a smaller version when the user uploads it, but since the design of this document hasn't been finalized yet, I was looking for something more dynamic. Also, this document only needs to be printed up once, while the image uploaded is displayed at various places in the app numerous times.
Using javascript to resize it while keeping its proportions, it was printing fine for a while. After adding a margin for styling, the printer started printing the image at its full size. I'm assuming it's the margin. It looks fine on screen but pushes everything off the page on paper.
This led me to look into resizing it on the server, in the C# code, but we use user images uploaded to the database, and I can't seem to find the right time or place in the page life cycle to access and change the width and height. I've tried the various methods on the web using Bitmaps, but they all want a file, when I am using a FileDownloader page as the image url.
Perhaps I'm looking in the wrong place entirely and need to go back to the client. Advice and help is appreciated.
As long as your FileDownloader page returns the proper resized image, it shouldn't matter that you're not point to an actual image.
I'd something like this in your FileDownloader page (pseudo code):
using (Image img = LoadImageFromDatabase())
{
using (Image resized = ResizeImage(img))
{
Response.Clear();
// Set proper headers
using (MemoryStream ms = new MemoryStream())
{
resized.Save(ms); // maybe the function isn't called Save, can't remember a 100%
ms.Seek(0); // Can't remember if this is necessary
Response.BinaryWrite(ms);
}
}
}
Like I mentioned it's highly pseudo code, but it should be straight forward with a Visual Studio open, I just haven't access to it right now, and it's been quite a while since I last used this (since I'm stored the resized images like most other in this question recommends - I do so too, however I realize this is not an option for you)
When you are going to have to resize an image to known constraints, and there's the possibility of having to do that multiple times, I'd always advocate doing the resize once (on upload) and storing the result. Of course, you don't say that you need to retain the original image size, but if you do, then you just have to store the image twice - once original size and once at the resized dimensions.
Once you've done that, you can worry about defining your print layout based on the known dimensions of the resized image, and not have to faff about resizing for each use.
I would suggest converting on upload and possibly saving both images in case you want to let the user click through to the full image. Using this model you only do the conversion once and can render either size image. The GetThumbnailImage() method on the Image class will do what you desire, something like this:
String imageFile = uploadedFileName;
Image baseImage = Image.FromFile(imageFile);
Image thumbImage = baseImage.GetThumbnailImage(300,300,..., ...);
SaveMyImage(baseImage);
SaveMyImage(thumbImage);
Be sure to check the documentation for the parameters to GetThumbnailImage() to verify scaling issues and callback handling.
Could you implement such a process:
User sends an image
Image is opened by a function/routine/script, while the user waits
Image is resized on the fly and saved in the correct location which returns a code for success
User receives a message depending of the return value of the script.
EDIT:
I agree with most of the replies you got here.
If the pictures are stored in a database you need to first make thumbmails for all pictures and put them in the same database, then you need to implement a process to create the thumbmails on the fly when adding new pictures.
Disclaimer: I'm suggesting the open-source library I designed for this purpose. I'm definitely biased, but 4 years and thousands of happy users justify my bias :)
You shouldn't be resizing images inside an .ASPX page, or serving them either. Images should be handled in separate requests by a HttpModule so responsiveness doesn't suffer.
If you have some kind of ID in SQL for each image, you can use the SqlReader VirtualPathProvider to make it accessible via a URL, like /sqlimages/id
Combine that with this free, open-source dynamic image resizing module, and you're set.
You'll simply reference images like this: http://localhost/sqlimages/id?width=300&height=200 from your HTML, and you may not even have to write a line of C#.
If you write your own solution, read these 28 pitfalls you should avoid, so you don't end up crashing the server.
Hope this helps!

Change the resolution of a jpeg image using C#

I need to modify the vertical and horizontal resolutions without changing the image dimensions.
Check out the Bitmap.SetResolution Method.
If all you have is GDI, have a look at this link.
You can save the Bitmap to a JPEG file using this snippet:
bmp.Save("picture.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
The resolution is contained in EXIF tags within the JPEG file.
Here's one article that gives source code for doing similar things in C#:
http://www.codeproject.com/KB/graphics/EXIF_tag_Editor.aspx

Categories

Resources