AlphaBlendMatrix and how to resize the image by C#

The description about Alpha Blending in MSDN is as follows

Alpha Blending Lines and Fills

In GDI+, a color is a 32-bit value with 8 bits each for alpha, red, green, and blue. The alpha value indicates the transparency of the color — the extent to which the color is blended with the background color. Alpha values range from 0 through 255, where 0 represents a fully transparent color, and 255 represents a fully opaque color.

Alpha blending is a pixel-by-pixel blending of source and background color data. Each of the three components (red, green, blue) of a given source color is blended with the corresponding component of the background color according to the following formula:

displayColor = sourceColor × alpha / 255 + backgroundColor × (255 – alpha) / 255

For example, suppose the red component of the source color is 150 and the red component of the background color is 100. If the alpha value is 200, the red component of the resultant color is calculated as follows:

150 × 200 / 255 + 100 × (255 – 200) / 255 = 139

Here I learned how to merge two images in C# and designed a simple program to show how it does.

  1. Click on openfile button to select the image you want. It involves with a function named ResizeImage, and I would like to introduce this one later on.
  2. Regard the right image as destImage, thus the left one is the srcImage.

alphablending1

2. Click on the AlphaBlend button, how it shows  as follows

alphablending2

The Code snippet of function AlphaBlendMatrix:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace fuckingCsharp
{
    class Blend
    {
        //merging two images in C#(paint one image on top of another with some level of
        // transparency as opposed to using one color as a transparency mask)
        public static Bitmap AlphaBlendMatrix(Bitmap destImage, Bitmap srcImage, byte alpha)
        {
            Bitmap alphaBlendImage = (Bitmap)destImage.Clone();
            //specify the desired alpha
            //alpha ranges from 0 to 255, 127 would be translucent
            float alphaNorm = (float)alpha / 255.0F;
            //矩阵
            ColorMatrix matrix = new ColorMatrix(new float[][]{
                        new float[]{1F,0,0,0,0},//red
                        new float[]{0,1F,0,0,0},//green
                        new float[]{0,0,1F,0,0},//black
                        new float[]{0,0,0,alphaNorm,0},//alpha
                        new float[]{0,0,0,0,1F}//translation
                    });
            //ImageAttributes
            ImageAttributes imageAttributes = new ImageAttributes();
            imageAttributes.SetColorMatrix(matrix);
            //paint the source image on to the dest using the matrix
            int offsetX = (destImage.Width - srcImage.Width) / 2;
            int offsetY = (destImage.Height - srcImage.Height) / 2;

            using (Graphics g = Graphics.FromImage(alphaBlendImage))
            {
                //指定源色与背景色混合方式
                g.CompositingMode = CompositingMode.SourceOver;
                //绘制合成图像的呈现质量
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.DrawImage(
                    srcImage,
                    new Rectangle(offsetX, offsetY, srcImage.Width, srcImage.Height),//destination matrix
                    0, 0, //upper-left corner of source rectangle
                    srcImage.Width,
                    srcImage.Height,
                    GraphicsUnit.Pixel,
                    imageAttributes
                    );
                //DrawImage(Image, Rectangle, Single, Single, Single, Single, GraphicsUnit, ImageAttributes)
                //GraphicsUnit 数据的度量单位
            }
            return alphaBlendImage;



        }
    }
}

The code snippet of function ResizeImage:

The key is how to get the ratio

 public static Bitmap ResizeImage(Image srcImage, int destFrameWidth, int destFrameHeight, bool retainDestDimensions)
        {
            double srcImageWidth = (double)srcImage.Width;
            double srcImageHeight = (double)srcImage.Height;

            //计算出比率
            double destToSrcRatioWidth = (double)destFrameWidth / srcImageWidth;
            double destToSrcRatioHeight = (double)destFrameHeight / srcImageHeight;
            //选择较小的比率
            double destToSrcRatio = destToSrcRatioWidth < destToSrcRatioHeight ? destToSrcRatioWidth : destToSrcRatioHeight;
            //得到调整好的大小,比率较小的保持 destFrame,填充满目标框图,比率大的缩进目标框图
            //即resizedImageWidth or Height 必然有一个小于 destFrameWidth or Height
            int resizedImageWidth = (int)(srcImageWidth * destToSrcRatio);
            int resizedImageHeight = (int)(srcImageHeight * destToSrcRatio);
            //比率较小的offset=0,计算得到居中偏移量
            int offsetX = Math.Abs(destFrameWidth-resizedImageWidth)/2;
            int offsetY = Math.Abs(destFrameHeight-resizedImageHeight)/2;

            Bitmap canvas = null;
            //参数retainDestDimensions 是否保留目标框图
            if (retainDestDimensions)
            {
                canvas = new Bitmap(destFrameWidth, destFrameHeight);
            }
            else
            {
                canvas = new Bitmap(resizedImageWidth,resizedImageHeight);
            }
            using (Graphics gfx = Graphics.FromImage(canvas))
            {
                //高质量的双三次插值法,执行筛选以确定高质量的收缩
                gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
                if (retainDestDimensions)
                {
                    gfx.FillRectangle(Brushes.Gray, 0, 0, destFrameWidth, destFrameHeight);
                    gfx.DrawImage(srcImage, offsetX, offsetY, resizedImageWidth, resizedImageHeight);
                   
                    
                }
                else
                {
                    gfx.FillRectangle(Brushes.Gray,0,0,resizedImageWidth,resizedImageHeight);
                    gfx.DrawImage(srcImage,0,0,resizedImageWidth,resizedImageHeight);
                }
            }

            return canvas;

        }

 

Here are several links which could be my references

https://msdn.microsoft.com/en-us/library/e3f5k4xc(v=vs.110).aspx

http://ithoughthecamewithyou.com/post/Fastest-image-merge-%28alpha-blend%29-in-GDI2b.aspx

2 thoughts on “AlphaBlendMatrix and how to resize the image by C#

发表评论

电子邮件地址不会被公开。 必填项已用*标注