Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET CF Bitmap class quality is poor

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

like image 477
Chris Avatar asked Feb 26 '23 05:02

Chris


2 Answers

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:

  • A simple Faux-antialiasing for .NET CF is described here: Anti aliasing DrawLine on CE
  • A related question with suggestions for graph drawing on .NET CF: Graphs in .NET CF
  • An external library e.g. http://www.opennetcf.com/library/sdf/, http://drawingcf.codeplex.com/
  • P/Invoke
like image 58
Eamon Nerbonne Avatar answered Mar 04 '23 10:03

Eamon Nerbonne


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.

like image 40
David Avatar answered Mar 04 '23 10:03

David