按照大小限制等比例压缩图片

需求:

把上图中的img标签中的base64图片转换为图片并压缩为小于100KB

页面布局:

代码:

<div class="layui-form-item">
    <div class="layui-inline">
        <label class="layui-form-label">未加密密码</label>
        <div class="layui-input-block">
            <input type="text" name="UnEncryptPwd" autocomplete="off" placeholder="请输入密码" class="layui-input" />
        </div>
    </div>

    <div class="layui-inline">
        <button type="button" id="EncryptPwd" class="layui-btn layui-btn-primary">加密</button>
        <div class="layui-input-block">
            <input type="text" name="DecryptPwd" placeholder="" autocomplete="off" class="layui-input" />
        </div>
    </div>
</div>
<div class="layui-form-item">
    <div class="layui-inline">
        <label class="layui-form-label">已加密密码</label>
        <div class="layui-input-block">
            <input type="text" name="EncryptPwd" autocomplete="off" placeholder="请输入密码" class="layui-input" />
        </div>
    </div>

    <div class="layui-inline">
        <button type="button" id="DecryptPwd" class="layui-btn layui-btn-primary">解密</button>
        <div class="layui-input-block">
            <input type="text" name="txtDecryptPwd" placeholder="" autocomplete="off" class="layui-input" />
        </div>
    </div>
</div>
<div class="layui-form-item">
    <div class="layui-inline">
        <button type="button" id="btnCompress" class="layui-btn layui-btn-primary">上传图片</button>
        <input type="file" id="input_upload" style="display: none;" accept="image/*" />
        <img class="layui-upload-img" id="img_preview" />
        <button type="button" id="btn_ckeditor_content" class="layui-btn layui-btn-primary">获取ckeditor内容</button>
    </div>
</div>
<div class="layui-form-item">
    <div class="layui-inline">
        <textarea id="myEditor" name="Content" cols="100" data-sample="1"></textarea>
    </div>
</div
布局代码

页面初始化完成加载ckeditor的内容

<script type="text/javascript">
    $(function () {
        //CKeditor
        var ckeditor_object = CKEDITOR.replace('myEditor', { height: '375px', width: '800px', customConfig: '/ckeditor_coustom.js' });

        $.post("/Ashx/Upload.ashx", {
            action: "ReplaceBase64Str2ImgPath"
        }, function (data) {
            data = JSON.parse(data);
            var img_html = data.msg;
            ckeditor_object.setData(img_html);
        });
    });
</script>
初始化ckeditor内容

后台响应请求

HttpRequest request;
HttpResponse response;
public void ProcessRequest(HttpContext context)
{
    request = context.Request;
    response = context.Response;
    //允许跨域
    context.Response.AddHeader("Access-Control-Allow-Origin", "*");
    //允许的请求方式 GET POST DELETE...
    context.Response.AddHeader("Access-Control-Allow-Methods", "*");

    //context.Response.ContentType = "text/plain";
    string action = context.Request.Params["action"];
    MethodInfo methodinfo = GetType().GetMethod(action);
    methodinfo.Invoke(this, null);
}

public void ReplaceBase64Str2ImgPath() {
    string txt_path = @"G:\zhyue\backup\项目修改-工作日常\2018-08-15 图片等比例压缩 大小小于100k\a.txt";
    string txt_html = File.ReadAllText(txt_path);

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(txt_html);

    //从string获取所有img标签
    var img_nodes = doc.DocumentNode.SelectNodes("//img");
    if (img_nodes != null && img_nodes.Count > 0)
    {
        img_nodes.ToList().ForEach(img_node =>
        {
            string base64str = img_node.Attributes["src"].Value;//img的src属性 即base64字符串
            string relative_savepath= "/upload/img/" + DateTime.Now.ToString("yyyyMM") + "/";//压缩后的图片保存的相对路径

            //将base64转换为img图片 并另存为图片
            string file_path = Base64Str2Image(relative_savepath,base64str);//压缩后的图片绝对路径
            if (File.Exists(file_path))
            {
                //压缩后的图片名称
                string compress_img_name = Guid.NewGuid().ToString("N") + Path.GetExtension(file_path);
                relative_savepath += compress_img_name;
                //压缩图片到100KB以下
                string compress_img_path = Path.GetDirectoryName(file_path) + @"\" + compress_img_name;
                if (CompressImage(file_path, compress_img_path, 80, 100))
                {
                    File.Delete(file_path);//删除原图 保留压缩后的图片

                    //重写img_node的属性
                    img_node.Attributes["src"].Value = relative_savepath;
                }
            }
        });
    }

    response.Write("{\"code\":0,\"msg\":\"" + doc.DocumentNode.InnerHtml.Replace("\"","\\\"").Replace("\r\n","").Replace("\n","") + "\"}");
}
后台响应

base64转图片

/// <summary>
/// 将base64字符串转图片 并返回图片保存的绝对路径
/// </summary>
/// <param name="relative_savepath">"/upload/img/" + DateTime.Now.ToString("yyyyMM") + "/";</param>
/// <param name="base64str"></param>
/// <returns></returns>
private string Base64Str2Image(string relative_savepath,string base64str)
{
    string file_path = string.Empty;
    if (base64str.Contains("data:image"))
    {
        string[] str_arr = { ";base64," };
        string[] base64s = base64str.Split(str_arr, StringSplitOptions.None);
        string extension = "." + base64s[0].Split('/')[1];
        //图片保存路径
        //string savePath = "/upload/img/" + DateTime.Now.ToString("yyyyMM") + "/";
        //绝对路径
        string absolute_path = HttpContext.Current.Server.MapPath(relative_savepath);
        if (!Directory.Exists(absolute_path)) Directory.CreateDirectory(absolute_path);

        //文件名称
        string fileName = Guid.NewGuid().ToString("N") + extension;
        //文件保存的绝对路径
        file_path = absolute_path + fileName;
        //将Base64String转为图片并保存
        byte[] arr2 = Convert.FromBase64String(base64s[1]);
        using (MemoryStream ms2 = new MemoryStream(arr2))
        {
            using (Bitmap bmp2 = new Bitmap(ms2))
            {
                bmp2.Save(file_path);
            }
        }
    }

    return file_path;
}
base64转图片

无损压缩图片

/// <summary>
/// 无损压缩图片
/// </summary>
/// <param name="sFile">原图片地址</param>
/// <param name="dFile">压缩后保存图片地址</param>
/// <param name="flag">压缩质量(数字越小压缩率越高)1-100</param>
/// <param name="size">压缩后图片的最大大小 KB</param>
/// <param name="sfsc">是否是第一次调用</param>
/// <returns></returns>
private bool CompressImage(string sFile, string dFile, int flag = 90, int size = 300, bool sfsc = true)
{
    using (Image iSource = Image.FromFile(sFile))
    {
        ImageFormat tFormat = iSource.RawFormat;
        //如果是第一次调用,原始图像的大小小于要压缩的大小,则直接复制文件,并且返回true
        FileInfo firstFileInfo = new FileInfo(sFile);
        if (sfsc == true && firstFileInfo.Length < size * 1024)
        {
            firstFileInfo.CopyTo(dFile);
            return true;
        }

        int dHeight = iSource.Height / 2;
        int dWidth = iSource.Width / 2;
        int sW = 0, sH = 0;
        //按比例缩放
        Size tem_size = new Size(iSource.Width, iSource.Height);
        if (tem_size.Width > dHeight || tem_size.Width > dWidth)
        {
            if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
            {
                sW = dWidth;
                sH = (dWidth * tem_size.Height) / tem_size.Width;
            }
            else
            {
                sH = dHeight;
                sW = (tem_size.Width * dHeight) / tem_size.Height;
            }
        }
        else
        {
            sW = tem_size.Width;
            sH = tem_size.Height;
        }

        using (Bitmap ob = new Bitmap(dWidth, dHeight))
        {
            Graphics g = Graphics.FromImage(ob);

            g.Clear(Color.WhiteSmoke);
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);

            g.Dispose();

            //以下代码为保存图片时,设置压缩质量
            EncoderParameters ep = new EncoderParameters();
            long[] qy = new long[1];
            qy[0] = flag;//设置压缩的比例1-100
            EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
            ep.Param[0] = eParam;

            try
            {
                ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo jpegICIinfo = null;
                for (int x = 0; x < arrayICI.Length; x++)
                {
                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
                    {
                        jpegICIinfo = arrayICI[x];
                        break;
                    }
                }
                if (jpegICIinfo != null)
                {
                    ob.Save(dFile, jpegICIinfo, ep);//dFile是压缩后的新路径
                    FileInfo fi = new FileInfo(dFile);
                    if (fi.Length > 1024 * size)
                    {
                        flag = flag - 10;
                        CompressImage(sFile, dFile, flag, size, false);
                    }
                }
                else
                {
                    ob.Save(dFile, tFormat);
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}
无损压缩

base64替换压缩后的结果:

 

posted @ 2018-08-15 16:34  zhyue93  阅读(863)  评论(0编辑  收藏  举报