4

I have some code that creates a graph using the Bitmap class. The quality of the produced bitmap, however, is pretty poor, how can I improve the quality of this? Note that I am using the Compact Framework!

Here is a few snippets of how I do various things:

Create a bitmap with a background based on an existing jpg

Bitmap bitmap = new Bitmap(filename);

I then create a Graphics class from the bitmap

Graphics myG = Graphics.FromImage(bitmap);

I then draw to the graphics like so:

myG.DrawLine(majorAxisPen, graphRect.Left, graphRect.Bottom, graphRect.Right, graphRect.Bottom);

After drawing everything I need to I then save out the Bitmap like so:

bitmap.Save(fileDestination, System.Drawing.Imaging.ImageFormat.Jpeg);

Here is the image it produces Poor quality image

Chris
  • 26,744
  • 48
  • 193
  • 345
  • 2
    The image produced really looks like what I'd expect from the code you have. Can you elaborate on what you mean by "poor" quality? is it aliasing that's the issue? Color problems? Compression artifacts? Feel free to show zoom-ins or marked up pieces of the image as representations. – ctacke Jan 31 '11 at 15:10
  • To me, the quality is not up to scratch. The background used, for example, is used elsewhere on a webpage (which is where this graph is shown) but it is very noticeable that the graph background is of poorer quality – Chris Jan 31 '11 at 15:14
  • out of curiosity, what set of circumstances leads you to generate images for a webpage using CF? Web servers aren't typically so restrained... – Eamon Nerbonne Jan 31 '11 at 15:24
  • We have a "box" running WinCE. We have a web interface that requires reporting, including graphs. I am going to be testing Javascript graphs soon but they come with limitations as most javascript libraries leak, especially on IE6 which some of our customers use (sigh). Making an application generate the images like this means the web browser only needs serve up an image as opposed to rendering VML or SVG etc. – Chris Jan 31 '11 at 15:38
  • Oh and CE 'cos the licensing is cheap :) – Chris Jan 31 '11 at 15:38
  • Question: Is the background noticeably lighter/darker when compared to your base image? Just from the dullness (and how it makes existing artifacts more visible) I have a feeling your base image may contain its own color profile which is not carried through to the output image. It might be useful to post your base image file. – David Jan 31 '11 at 16:45

4 Answers4

5

There are two sources of "low quality" you may encounter.

  1. The actual drawing to the graphics object may be low quality - i.e. the lines you draw may be aliased (pixelated).
  2. The low quality can be a side effect of the jpeg encoding when you output the graphics to a stream.

Every Graphics object has a number of properties that control the "quality" of the operations you can perform on the object. In particular, you should set SmoothingMode to HighQuality to avoid jaggies on line drawings. Unsupported in .NET Compact Framework.

To avoid compression artifacts, you can control jpeg compression parameters by manually controlling compression rather than using the (low-quality) default ImageFormat.Jpeg - unfortunately, doing so on CF is not possible without resorting to manual P/Invoking or a third party library. For a more extensive code sample for the full .NET Framework, see an answer I wrote to a similar question: How do you conver a HttpPostedFileBase to an Image?.

An easy alternative is to use use PNG, a lossless image format that does not degrade quality each time it is saved - given the simple geometric shapes of the example you posted, this won't even cost you anything in terms of file-size. Using another format may be your only option; customizing jpeg encoder parameters isn't possible in the Compact Framework since the ImageCodecInfo isn't available. If you really need Jpeg, you could attempt to use an external library (e.g. http://www.opennetcf.com/library/sdf/), or P/Invoke native methods directly to access platform-specific encoders.

Some possible approaches for anti-aliasing:

Community
  • 1
  • 1
Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166
2

You haven't said what is poor about the quality. Are there visible JPEG artifacts? Are the colors wrong? Are the lines jagged?

Without knowing what is the specific problem it's hard to give a solution.

Some possible problems/solutions:

The lines are jagged: Use Graphics.SmoothingMode to specify how the lines should be rendered.

The lines are jagged: Use a compression format suitable for line art: JPEG is not suitable for line art, GIF and PNG are.

There are compression artifacts: Recompressing already compressed (JPEG) graphics is not recommended. If you have an uncompressed source image, use that as your base instead.

There are compression artifacts: Specify a less lossy JPEG level, or use a lossless compression type like GIF or PNG.

David
  • 24,700
  • 8
  • 63
  • 83
1

At a glance, I'd say check the options availible in the Save call, I think you can specify the Jpeg quality value to use a higher one, or you could switch to a lossless compression like PNG there.

asawyer
  • 17,642
  • 8
  • 59
  • 87
0

Try experimenting with the graphics quality:

graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

In my experience, the lowest acceptable quality makes a relatively small file. The difference in visual quality between 90% and 100% is invisible, but the file will be up to 5x smaller at 90%.

Dave Swersky
  • 34,502
  • 9
  • 78
  • 118