.NET 6 combined with SkiaSharp to realize the splicing verification code function

From the initial sliding verification code to the realization of rotating verification code! Not only practiced the use of SkiaSharp, but also learned a lot. I saw a splicing verification code function on the Internet, and my hands were itchy. Combining the two verification codes implemented earlier, let's learn how to realize the splicing verification code function!

Effect preview

insert image description here

Realization principle

In fact, splicing verification codes is much simpler to implement than sliding verification codes and selecting verification codes, because splicing verification codes does not involve grooves and slider templates. All you need is a background image!
Get the picture : Get the background picture first. Convert background image to SKBitmap.
Get a random value : According to the width and height of the picture, set a fixed X-coordinate spacing spacingXand a Y-coordinate spacing spacingY, and then define a random value of X-coordinate randomXand Y-coordinate random value to randomY
cut the image horizontally : according to the obtained random value randomY, horizontally Cut the background image into 2 pieces to make it into two parts, top and bottom.
insert image description here
Cut the picture vertically : According to the obtained random value randomX, cut the upper half into two pieces vertically!
insert image description here
In this way, we get 4 pictures.
Make the upper half left and right two pictures. Replace the position to form a new picture
insert image description here
Combine the new picture with the lower part to form a picture.
insert image description here
In this way, we have completed the picture of stitching the verification code. Pass him to the front.
The front end positions the slider to the upper half according to the data passed by the server. Then control the movement of the upper part of the picture to achieve the effect of splicing the verification code!

code part

The part of getting the background image has been mentioned earlier.
You can refer to: NET 6 realizes the generation of sliding verification code (6), verification code background image, slider image and groove image

Get background image

//拼接验证码没有模板,只需要背景图
//获取背景图
var background = await _resourceManager.RandomBackground();

Convert the background image toSKBitmap

 using var backgroundImage = SKBitmap.Decode(background);

Calculation interval

//X坐标间距
int spacingX = backgroundImage.Width / 8;
//Y坐标间距
int spacingY = backgroundImage.Height / 4;

The interval is defined mainly to generate random values ​​for the X and Y axes.

define random value

int randomX = _random.Next(spacingX, backgroundImage.Width - backgroundImage.Width /5);
int randomY = _random.Next(spacingY, backgroundImage.Height - spacingY);

Define X-axis random value randomX and Y-axis random value randomY .
**randomY**: The main function of randomY is to randomly cut the background image into upper and lower parts.
**randomX **The main function is to randomly cut the background image into left and right parts.

Cut the background image into upper and lower parts

First define a method, the function of this method is to cut the specified picture into two parts according to the incoming content.

public static List<byte[]> SplitImage(int pos,bool direction,SKBitmap img)
        {
    
    
            int StartImageWidth,
                StartImageHeight,
                EndImageWidth,
                EndImageHeight;
            int EndScanX, EndScanY;
            int ImageWidth = img.Width;
            int ImageHeight = img.Height;

            StartImageWidth = direction ? ImageWidth : pos;
            StartImageHeight = direction ? ImageHeight - pos : ImageHeight;
            EndImageWidth = direction ? ImageWidth : ImageWidth - StartImageWidth;
            EndImageHeight = direction ? pos : ImageHeight;
            EndScanX = direction ? 0 : pos;
            EndScanY = direction ? StartImageHeight : 0;


            using var StartImage = new SKBitmap(StartImageWidth, StartImageHeight);
            using var StartCanvas = new SKCanvas(StartImage);
            SKRect StartSourceRect = new SKRect(0, 0, StartImageWidth, StartImageHeight);
            SKRect StartDestRect = new SKRect(0, 0, StartImageWidth, StartImageHeight);
            StartCanvas.DrawBitmap(img, StartSourceRect, StartDestRect);

            using var EndImage = new SKBitmap(EndImageWidth, EndImageHeight);
            using var EndCanvas = new SKCanvas(EndImage);
            SKRect EndSourceRect = new SKRect(EndScanX, EndScanY, EndScanX + EndImageWidth, EndScanY + EndImageHeight);
            SKRect EndDestRect = new SKRect(0, 0, EndImageWidth, EndImageHeight);
            EndCanvas.DrawBitmap(img, EndSourceRect, EndDestRect);
            List<byte[]> result = new List<byte[]>();
            using var StartImg = SKImage.FromBitmap(StartImage);
            using var StartData = StartImg.Encode(SKEncodedImageFormat.Png, 100);
            using var EndImg = SKImage.FromBitmap(EndImage);
            using var EndData = EndImg.Encode(SKEncodedImageFormat.Png, 100);
            result.Add(StartData.ToArray());
            result.Add(EndData.ToArray());
            return result;

        }

The SplitImage method has 3 parameters:
pos : Split point, which refers to where to start cutting on the image.
direction : cutting direction. true for the horizontal direction, false for the vertical direction!
img : the image to be cut.

int StartImageWidth,
    StartImageHeight,
    EndImageWidth,
    EndImageHeight;
int EndScanX, EndScanY;
int ImageWidth = img.Width;
int ImageHeight = img.Height;

Because the picture is to be cut into 2 pictures, it StartImageWidthmeans StartImageHeightthe width and height of the first picture. EndImageWidthand EndImageHeightrepresent the width and height of the second image.
EndScanXIndicates the cutting point of the X coordinate, and EndScanYrepresents the cutting point of the Y coordinate.
Next, define two respectively SKCanvas, StartCanvasand EndCanvas. Represents the canvas of the first image and the canvas of the second image. After defining, define two more SKRect. SKRectRepresents a rectangle, he has 4 parameters. leftare , top, rightand , respectively bottom. I just saw these 4 parameters a bit confused, what does this mean? Immediately reacted. where lertand topdetermine the coordinates of the upper left corner. rightand bottomdetermine the coordinates of the lower right corner. Then use DrawBitmapthe method to get two pictures.
It should be noted that what is returned is a List<byte[]>. The data of two pictures are saved in it byte[]. Why not return the List directly? because it is used in the code using var. If List is returned. With this method, the SKBitmaps of the two images are released. Then use the SKBitmap of these two pictures again, it will be abnormal. If it is used var, it is not easy to find a suitable time to release them. So a List<byte[]> is returned. There is no delay in this way.

With this method, we can cut the picture into two required pictures according to the requirements.
Cut the picture into upper and lower parts:

 List<byte[]> bgImageList = CaptchaImageUtils.SplitImage(randomY, true, backgroundImage);
using var bgImage0 = SKBitmap.Decode(bgImageList[0]);
using var bgImage1 = SKBitmap.Decode(bgImageList[1]);

Cut the upper half of the image into left and right parts

List<byte[]> bgImageTopList = CaptchaImageUtils.SplitImage(randomX, false, bgImage0);
using var bgImageTop0 = SKBitmap.Decode(bgImageTopList[0]);
using var bgImageTop1 = SKBitmap.Decode(bgImageTopList[1]);

The method of use SplitImageis to cut the upper half of the upper and lower parts in the figure that has just been cut into two left and right parts. At this point, we have 4 images!

Stitch pictures

Our plan is to stitch bgImageTop0 together bgImageTop1 , but the order of stitching is bgImageTop1+bgImageTop0. In this way, a picture like this is obtained, we call it SliderImage
insert image description here
and then splicing SliderImagewith bgImage1and is completed.
Let's take a look at the splicing method first, give this splicing method a name, let's call ConcatImageit. The specific code is:

public static byte[] ConcatImage(bool direction,int width,int height, params SKBitmap[] imgArr)
{
    
    
    int pos = 0;
    using var NewImage = new SKBitmap(width, height);
    using var NewImageCanvas = new SKCanvas(NewImage);
    foreach(var img in imgArr)
    {
    
    
        float x = direction ? pos : 0;
        float y = direction ? 0 : pos;
        NewImageCanvas.DrawBitmap(img, x,y);
        pos += direction ? img.Width : img.Height;
                
    }
    using var NewImg = SKImage.FromBitmap(NewImage);
    using var NewData = NewImg.Encode(SKEncodedImageFormat.Png, 100);
    return NewData.ToArray();
}

ConcatImageThe method has 4 parameters,
direction : booltype, indicating the splicing direction, true for horizontal splicing, false for vertical splicing.
width : inttype, the width of the spliced ​​image
height : inttype, the height of the spliced ​​image
imgArr : paramstype, the array of the spliced ​​image

Define SKBitmapand respectively SKCanvas. Then loop through the array. Stitch the pictures together and finally return one byte[].

After stitching is complete, return the picture to the front end.

return new ConcatImageCaptchaInfo
{
    
    
    BackgroundImage = bgImage.ToBase64String(SKEncodedImageFormat.Png),
    SliderImage = null,
    BackgroundImageWidth = bgImage.Width,
    BackgroundImageHeight = bgImage.Height,
    SliderImageWidth = 0,
    SliderImageHeight = 0,
    RandomX = randomX,
    RandomY = randomY,
    Tolerant = 0.05F,
    CaptchaType = CaptchaTypeConstant.CONCAT
};

ToBase64StringExtension methods written for myself. You can refer to .Net 6 to implement the rotation verification code . This article has written this method.
The front-end code is basically the same as the previous sliding verification code. Just change it a little bit!

Summarize

There are other types of verification codes, such as click verification codes, graphic verification codes, etc. Will gradually improve.

Click on the official account card below to follow me! Learn together and progress together!

Guess you like

Origin blog.csdn.net/sd2208464/article/details/128603577