3

I have the following task. Take a base image and overlay on it another one. The base image is 8b png as well as overlay. Here are the base (left) and overlay (right) images.

Overlay image Overlay image

Here is a result and how it must look.

enter image description here enter image description here

The picture in the left is a screenshot when one picture is on top of another (html and positioning) and the second is the result of programmatic merging.

As you can see in the screenshot the borders of the text is darker. Also here are the sizes of the images

  • Base image 14.9 KB
  • Overlay image 6.87 KB
  • Result image 34.8 KB

The size of the resulting image is also huge

Here is my code that I use to merge those pictures

/*...*/
public Stream Concatinate(Stream baseStream, params Stream[] overlayStreams) {
    var @base = Image.FromStream(baseStream);
    var canvas = new Bitmap(@base.Width, @base.Height);
    using (var g = canvas.ToGraphics()) {
        g.DrawImage(@base, 0, 0);
        foreach (var item in overlayStreams) {
            using (var overlayImage = Image.FromStream(item)) {
                try {
                    Overlay(@base as Bitmap, overlayImage as Bitmap, g);
                } catch {

                }
            }
        }
    }
    var ms = new MemoryStream();
    canvas.Save(ms, ImageFormat.Png);
    canvas.Dispose();
    @base.Dispose();
    return ms;
}

/*...*/
/*Tograpics extension*/
public static Graphics ToGraphics(this Image image,
    CompositingQuality compositingQuality = CompositingQuality.HighQuality,
    SmoothingMode smoothingMode = SmoothingMode.HighQuality,
    InterpolationMode interpolationMode = InterpolationMode.HighQualityBicubic) {
    var g = Graphics.FromImage(image);

    g.CompositingQuality = compositingQuality;
    g.SmoothingMode = smoothingMode;
    g.InterpolationMode = interpolationMode;
    return g;
}
private void Overlay(Bitmap source, Bitmap overlay, Graphics g) {
    if (source.Width != overlay.Width || source.Height != overlay.Height)
        throw new Exception("Source and overlay dimensions do not match");
    var area = new Rectangle(0, 0, source.Width, source.Height);
    g.DrawImage(overlay, area, area, GraphicsUnit.Pixel);
}

My questions are

  • What should I do in order to merge images to achieve the result as in the screenshot?
  • How can I lower the size of the result image?
  • Is the System.Drawing a suitable tool for this or is there any better tool for working with png for .NET?
Oybek
  • 7,016
  • 5
  • 29
  • 49

1 Answers1

3

The answers to your questions are: 1) Just call method ToGraphics with a argument CompositingQuality.Default instead of using default argument values like in the example:

using (var g = canvas.ToGraphics(compositingQuality: CompositingQuality.Default)) 

The problem is with CompositingQuality.HighQuality is that it makes a composition of both images into one, but you want to make an overlay, not to make a composition of two images.

2) The size will be similar to the one you specified and that can not be changed, it is due to a image format.

3) If you are programming in c# for desktop, than System.Drawing is the best choice as far as I know.

Nikola Davidovic
  • 8,556
  • 1
  • 27
  • 33