2

I try to create a thumbnail image from the original image in order to use in my asp.net MVC application.

Using the code below, I am able to do the task but the result is not clear enough.

My question is if there is a better way to do this and if it is possible to make the result clear as on the expected result on the image.

Here is my code :

    var tracedPath = @"C:\Users\co\Desktop\traced.png";
        var targetPath = @"C:\Users\co\Desktop\thumbnail.png";

        Bitmap bmpSource = new Bitmap(tracedPath);
        Bitmap bmpTarget = new Bitmap(224, 210);

        var width = 85;
        var height = 210;
        var bmpResizedSource = new Bitmap(bmpSource, width, height);

        using (Graphics grD = Graphics.FromImage(bmpTarget))
        {
            grD.DrawImage(bmpResizedSource, new RectangleF((224 - 75) / 2, 5, 75, 200), new RectangleF(0, 0, 85, 210), GraphicsUnit.Pixel);
        }

        bmpTarget.Save(targetPath);

        Color pixel = Color.Transparent;
        for (int x = 0; x < 224; x++)
        {
            for (int y = 0; y < 210; y++)
            {
                pixel = bmpTarget.GetPixel(x, y);
                if (pixel.A > 0)
                {
                    bmpTarget.SetPixel(x, y, Color.Black);
                }
            }
        }
        bmpTarget.Save(targetPath);

Here is the image to explain what I want to do : enter image description here

Coskun Ozogul
  • 2,389
  • 1
  • 20
  • 32
  • What you did to the image is shrink it and enhanced the lines thickness (bold). By shrinking you will loose pixels in the process. You might want to Bold the image first then resize it. then max the contrast to keep the black color clean – Franck Apr 25 '19 at 12:22
  • How to make the original image bolder ? Should I find an algorithm? I searched but for now, I don't have a solution for this. – Coskun Ozogul Apr 25 '19 at 12:25
  • You could try to use drawimage to add one or more of those images on top of each other, offset by one pixel in various directions. Make sure to make the white areas transparent first, of course.. – TaW Apr 25 '19 at 12:32
  • The easiest algorithm is get all the x,y black pixels you have. Then growth the list by taking all 8 pixels surrounding each of those pixels Then simply draw black on each of those pixels. Don't forget to remove duplicated coordinate it creates and you can also extend the selection 1 pixel further ( or more ) to thicken the lines – Franck Apr 25 '19 at 12:34
  • [Here](https://stackoverflow.com/questions/34116706/how-to-repair-dimmed-image-of-book-page/34121073?r=SearchResults&s=8|26.8796#34121073) is an example you can start with. It uses a ColorMatrix to enhance an image via contrast and gamma. You can take this route: Scale it down, increase gamma&contrast, repeat as needed.. – TaW Apr 25 '19 at 13:01

2 Answers2

2

Not sure if this is going to help you in your situation but as i needed to add a picture this has to be posted as an answer... The answer to your question in gerneral is very dependant on the image content. If your always going to have a black and white sketch this will help: Rescale your image, apply a low radius gaus to it, and increase its contrast / decrease its transparency the result i show below. You can differ the line thickness by changing the radius of the gaus filter. Please note that a high gaus will cause your image to dissapear completly enter image description here

*Also consider if you could not use paths instead of images to display shapes like this

Denis Schaf
  • 2,478
  • 1
  • 8
  • 17
  • The original image is drawn by a designer. I should reproduce the same thing. I am going to try what you adviced. Thanks. – Coskun Ozogul Apr 25 '19 at 12:26
2

Here is a function drawn mostly from this post

Bitmap Bolden(Bitmap bmp0)
{
    float f = 2f;

    Bitmap bmp = new Bitmap(bmp0.Width, bmp0.Height);
    using (Bitmap bmp1 = new Bitmap(bmp0, new Size((int)( bmp0.Width * f),
                                                   (int)( bmp0.Height * f))))
    {

        float contrast = 1f;

        ColorMatrix colorMatrix = new ColorMatrix(new float[][]
                {
            new float[] {contrast, 0, 0, 0, 0},
            new float[] {0,contrast, 0, 0, 0},
            new float[] {0, 0, contrast, 0, 0},
            new float[] {0, 0, 0, 1, 0},
            new float[] {0, 0, 0, 0, 1}
                });

        ImageAttributes attributes = new ImageAttributes();
        attributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default,
                                                ColorAdjustType.Bitmap);
        attributes.SetGamma(7.5f, ColorAdjustType.Bitmap);
        using (Graphics g = Graphics.FromImage(bmp))
           g.DrawImage(bmp1, new Rectangle(0, 0, bmp.Width, bmp.Height),
                    0, 0, bmp1.Width, bmp1.Height, GraphicsUnit.Pixel, attributes);

    }
    return bmp;
}

Result of applying it once:

enter image description here

You could apply it more often and upon the 2nd iteration use a contrast > 1..

Explanation: I first scale the original image and thereby create a little blur (anti-aliasing). Then I make all gray pixels darker by applying a large gamma and finally restore the orginal size. This is basically the same idea as Denis's post but in working GDI+ code..

TaW
  • 53,122
  • 8
  • 69
  • 111
  • Very nice! Thanks. When I take the thumbnail image, it is clear too. But when I copy it into the result image, it is not very clear. using (Graphics grD = Graphics.FromImage(bmpTarget)) { grD.DrawImage(bmpResizedSource, new RectangleF((224 - 75) / 2, 5, 75, 200), new RectangleF(0, 0, 85, 210), GraphicsUnit.Pixel); } – Coskun Ozogul Apr 25 '19 at 13:36
  • I copied the large image before getting the thumbnail and it is very clear. Many thanks. – Coskun Ozogul Apr 25 '19 at 14:07