【问题标题】:how to check if a base 64 encoded image contains any color but white in razor c#如何检查base 64编码图像是否包含剃须刀c#中的除白色以外的任何颜色
【发布时间】:2017-12-19 07:41:32
【问题描述】:

我正在处理一个包含 jSignature 元素的表单,它是一个 jquery 插件,用于将用户制作的签名存储到 base64 字符串(或其他格式)。

主要问题是,如果我尝试编辑列表中的条目,我需要能够检查签名是否为空。

如此简化;验证 base64 字符串是包含黑色还是纯白色。

现在我采取的不同方法以及它们失败的原因:

  • 保存空签名的源字符串并将其与新签名进行比较

这失败了,因为每当我在添加条目时有不同的分辨率时,源字符串都会与之前保存的不同,为空。

  • 在JS中创建一个方法来计算base64字符串中颜色的百分比量(如果不是100%白色,有签名)

这失败了,因为我需要能够将此方法返回的值存储在 c# 属性中。但显然razor的C#部分和内联JS不是同时存在的。这将有必要检查签名是否为空,如果显示 jSignature 元素以添加先前添加的图片的签名

  • 使用 C#(在 cshtml 中)创建类似的方法来检查图像的颜色

如果我可以访问应用程序的数据层(我确实有,但对于这个项目,最好不要在那里更改或添加任何东西),这将起作用。问题是我不能在 cshtml 文件中使用数据类型 Bitmap。

我真的只是在寻找一种可行的不同方法,但如果我应该添加任何代码 sn-ps 只是要求它,我会很乐意这样做。

感谢任何帮助!

编辑: 更新了cshtml的代码:

           @if (!editMode && !formDisabled || signatureEmpty)
            {
                <div class="form-group" style="margin:5%">
                    <div class="form-inline" for="sign">
                        <label class="control-label" style="float:left; margin-top:2%">Unterschrift</label>
                        <button type="button" class="btn btn-primary" style="float:right; margin-bottom:1%; background-color:dodgerblue" onclick="refreshSignature()"><span class="glyphicon glyphicon-refresh"></span></button>                    
                    </div>
                    <div style="width:100%; margin-left:0%;" height:auto" name="sign">
                        <div disabled="@formDisabled" id="signature" class="">

                        </div>
                    </div>
                </div>
            }
            else if(!signatureEmpty) //signature->show image 
            {
                <div class="form-group" style="margin:5%">
                    <div class="form-inline" for="signDisabled">
                        <label class="control-label" style="float:left">Unterschrift</label>
                    </div>
                    <img id="testtest" src="@zeitaufzeichnung.Signature"/> <!--format Signature: data:image/png;base64,i1234lkj123;k4;l1j34l1kj3j...-->
                </div>
            }
            else
            {
                <div class="form-group" style="margin:5%">
                    <label class="control-label" style="float:left">keine Unterschrift vorhanden</label>
                </div>
            }

以及应该改变C# signatureEmpty属性的java脚本方法(主要是checkIfSignatureIsEmpty方法):

function getColors(ctx) {

        // Get the canvas data
        var pixels = ctx.getImageData(0, 0, ctx.width, ctx.height),
            data = pixels.data,

        // Set up our output object to collect color data
        output = {};

        // For each color we encounter, check the
        // output object. If the color already exists
        // there, simply increase its counted value.
        // If it does not, create a new key.
        for (var i = 0; i < data.length; i += 4) {
            var r = data[i],
                g = data[i + 1],
                b = data[i + 2],
                col = rgbToHex(r, g, b);

            if (output[col])
                output[col]++
            else
                output[col] = 1
        }

        // Count total
        var total = 0;
        for (var key in output) {
            total = total + parseInt(output[key])
        }
        output.total = total;

        // Return the color data as an object
        return output;
    }

    function checkIfSignatureIsEmpty(source)
    {
        var img = new Image();
        img.src = source;
        img.id = "img";
        img.name = "img";

        img.onload=function(){
            var imageData = extract_colors(img);
            if (imageData[0] / imageData.total == 1) {
                return true;
            } else {
                return false;
            }
        }
    }

    function extract_colors(img) {
        var canvas = document.createElement("canvas");
        var c = canvas.getContext('2d');
        c.width = canvas.width = img.width;
        c.height = canvas.height = img.height;
        c.clearRect(0, 0, c.width, c.height);
        c.drawImage(img, 0, 0, img.width, img.height);
        return getColors(c);
    }

    function rgbToHex(r, g, b) {
        return ((r << 16) | (g << 8) | b).toString(16);
    }

【问题讨论】:

  • 使用 ajax 将 base64 字符串发送到服务器并进行计算没有选项吗?或者甚至计算它并将结果存储在服务器上?
  • 技术上是这样,但我更喜欢客户端的解决方案
  • 那么你自己回答了你的问题。将您的财产存储在 Javascript 中。客户端/浏览器上不存在 C#(很可能)。
  • 那么问题是我需要显示一个 jsignature 元素或一个签名的 img,我用剃刀 if/else 解决了我不能使用 javascript 变量 afaik
  • 而不是使用 c# 只需设置一个 javascript 变量。为 editMode 使用不同的查询字符串或路由值,然后使用 javascript 隐藏 div。

标签: c# jquery html razor jsignature


【解决方案1】:

我终于说服自己在应用程序的数据层中创建一个方法。

下面是代码,以防有人需要:

public static bool IsSignatureEmpty(string base64Source)
    {
        Bitmap signatureBM = null;

        try
        {
            byte[] byteBuffer = Convert.FromBase64String(base64Source.Replace("data:image/png;base64,", ""));
            MemoryStream memoryStream = new MemoryStream(byteBuffer);

            memoryStream.Position = 0;

            signatureBM = (Bitmap)Bitmap.FromStream(memoryStream);

            memoryStream.Close();
            memoryStream = null;
            byteBuffer = null;
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: " + e.Message);
        }

        int width = signatureBM.Width;
        int height = signatureBM.Height;

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                //Name==0 would equal the color white
                if (signatureBM.GetPixel(x, y).Name != "0")
                {
                    return false;
                }
            }
        }
        return true;
    }

如果您真的想使用纯 JS/Html,请使用上面的 js 代码并参考 Marco 的评论:

只需设置一个 javascript 变量,而不是使用 c#。为 editMode 使用不同的查询字符串或路由值,然后使用 javascript 隐藏 div

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-21
    • 2013-01-26
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多