用签字组成的图片,软件一键分分钟生成。

俩小时写的软件,生成签字图片分分钟,上传效果大家看看。猜猜是谁?

 好玩吧!

 

原理很简单。

1、遍历图片

2、判断当前点覆盖的签字区域的灰度值。

3、设定一个阈值,如果超过阈值,绘图签字区域。并且将原图对应的区域变浅。

下面是核心部分代码:


        private void btnCreateImg_Click(object sender, RoutedEventArgs e)
        {
            if (imagePen == null || imageImg == null)
            {
                MessageBox.Show("请选择原图!");
                return;
            }
            //原图尺寸
            int imageWidth = imageImg.PixelWidth;
            int imageHeight = imageImg.PixelHeight;
            //签字图尺寸
            int penWidth = imagePen.PixelWidth;
            int penHeight = imagePen.PixelHeight;
            int deepRate = int.Parse(tbDeepRate.Text);
            double shardowRate = double.Parse(tbShadowRate.Text);
            WriteableBitmap writeImage = new WriteableBitmap(imageWidth, imageHeight,
                72, 72, PixelFormats.Bgra32, null);
            bdTarget.Source = writeImage;
            //ARGB
            int totalSize = imageWidth * imageHeight;
            int penSize = penWidth * penHeight;
            byte[] b = new byte[4 * totalSize];
            byte[] penb = new byte[4 * penSize];
            byte[] writeImg = Enumerable.Repeat((byte)0xff, 4 * totalSize).ToArray();
            Int32Rect rect = new Int32Rect(0, 0, imageWidth, imageHeight);
            imageImg.CopyPixels(rect, b, 4 * imageWidth, 0);
            Int32Rect rectPen = new Int32Rect(0, 0, penWidth, penHeight);
            imagePen.CopyPixels(rectPen, penb, 4 * penWidth, 0);

            //白 0 黑 255
            byte[] avgB = new byte[totalSize];
            for (int i = 0; i < totalSize; i++)
            {
                avgB[i] = (byte)(255 - (b[i * 4 + 1] + b[i * 4 + 2] + b[i * 4 + 0]) / 3);
            }
            //白 0 黑 255
            byte[] avgP = new byte[penSize];
            for (int i = 0; i < penSize; i++)
            {
                avgP[i] = (byte)(255 - (penb[i * 4 + 1] + penb[i * 4 + 2] + penb[i * 4 + 0]) / 3);
            }
            int times = 1;
            int curIJ = 0;
            double maxClr = -1;
            int maxX = 0;
            int maxY = -1;
            Random rdm = new Random();
            while(true)
            {
#if false
                //斜着写
                maxY++;//增加一行
                if (maxY > curIJ || maxY >= imageHeight - penHeight)//最后一行
                {
                    curIJ++;
                    if (curIJ >= imageWidth - penWidth)
                    {
                        maxY = curIJ - (imageWidth - penWidth) + 1;
                        if (maxY >= imageHeight - penHeight)
                        {
                            break;
                        }
                    }
                    else
                    {
                        maxY = 0;
                    }
                }
                maxX = curIJ - maxY;
                maxClr = GetPixClr(maxX, maxY, penWidth, penHeight, imageWidth, avgB, avgP);
                if (maxClr < shardowRate * penSize)
                {
                    continue;
                }

#else
                if (maxY == -1)
                {
                    maxY = 0;
                }
                maxX++;
                if (maxX >= imageWidth - penWidth)
                {
                    maxX = 0;
                    maxY++;
                    if (maxY >= imageHeight - penHeight)
                    {
                        break;
                    }
                }
                maxClr = GetPixClr(maxX, maxY, penWidth, penHeight, imageWidth, avgB, avgP);
                if (maxY == 0)
                {
                    double rdmrate = shardowRate * rdm.Next(1, 7);
                    if (maxClr < rdmrate * penSize)
                    {
                        continue;
                    }
                }
                else if (maxClr < shardowRate * penSize)
                {
                    continue;
                }
#endif
                byte gray = 0;
                for (int i = 0; i < penWidth; i++)
                {
                    for (int j = 0; j < penHeight; j++)
                    {
                        if (avgB[(maxY + j) * imageWidth + maxX + i] > (deepRate + avgP[j * penWidth + i]))
                        {
                            avgB[(maxY + j) * imageWidth + maxX + i] -= (byte)(deepRate + avgP[j * penWidth + i]);
                        }
                        else
                        {
                            avgB[(maxY + j) * imageWidth + maxX + i] = 0;
                        }
                        gray = (byte)((avgP[j * penWidth + i]) * 0.5);
                        if (writeImg[((maxY + j) * imageWidth + maxX + i) * 4] > gray)
                        {
                            writeImg[((maxY + j) * imageWidth + maxX + i) * 4] -= gray;
                        }
                        else
                        {
                            writeImg[((maxY + j) * imageWidth + maxX + i) * 4] = 0;
                        }
                        if (writeImg[((maxY + j) * imageWidth + maxX + i) * 4 + 1] > gray)
                        {
                            writeImg[((maxY + j) * imageWidth + maxX + i) * 4 + 1] -= gray;
                        }
                        else
                        {
                            writeImg[((maxY + j) * imageWidth + maxX + i) * 4 + 1] = 0;
                        }

                        if (writeImg[((maxY + j) * imageWidth + maxX + i) * 4 + 2] > gray)
                        {
                            writeImg[((maxY + j) * imageWidth + maxX + i) * 4 + 2] -= gray;
                        }
                        else
                        {
                            writeImg[((maxY + j) * imageWidth + maxX + i) * 4 + 2] = 0;
                        }
                    }
                }
                writeImage.WritePixels(new System.Windows.Int32Rect(0, 0, imageWidth, imageHeight), writeImg,
                    imageWidth * 4, 0);
                tbCount.Text = times.ToString();
                times++;
                DoEvents();
            }


            RenderTargetBitmap bmp = new RenderTargetBitmap((int)bdTarget.ActualWidth, (int)bdTarget.ActualHeight,
               96, 96, PixelFormats.Pbgra32);
            bmp.Render(bdTarget);
            JpegBitmapEncoder encode = new JpegBitmapEncoder();
            encode.Frames.Add(BitmapFrame.Create(bmp));
            MemoryStream ms = new MemoryStream();
            encode.Save(ms);
            byte[] byteSource = ms.ToArray();

            File.WriteAllBytes("Export.jpg", byteSource);
        }

        private double GetPixClr(int x, int y, int penWidth, int penHeight, int imgWidth, byte[] avgB, byte[] avgP)
        {
            double totalClr = 0;
            for (int i = 0; i < penWidth; i++)
            {
                for (int j = 0; j < penHeight; j++)
                {
                    totalClr += avgB[(y + j) * imgWidth + x + i] * (avgP[j * penWidth + i] / 255.0);
                }
            }
            return totalClr;
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值