上传文件 file upload 学习笔记分分快三计划

作者:分分快三计划

将文件调换为图片

文件转变为图片实际上首先须求读取文件,这里要求用到FileReader。

function setImgIntoCanvas(imgFile) {
  var reader = new FileReader();

  reader.onloadend = function (e) {
    var dataURL = e.target.result;
    img.onload = function (event) {
      var ctx = document.getElementById('target_canvas').getContext('2d');
      //将canvas大小设置为和图片一样大
      setCanvasSize(event.target.naturalWidth, event.target.naturalHeight);
      ctx.drawImage(img, 0, 0);
      setCanvasImgToDownloadLink();
    };
    img.src = dataURL;
  };
   reader.readAsDataURL(imgFile);
   resetWatermark();
};

 

如上为骨干代码,通过FileReaderreadAsDataURL函数读取文件能够获取Base64格式的图样数据,将图片数据赋值给一个Image对象。

要把那一个控件写好的话,必要一些设计情势,可是这篇不会提到那个,小编只是想大约的说说经过和行使到的API方法,怎样去规划就交由你们本身了。

将功用写进博客里

关于这一部分先是要提请JS权限。

附带即便观看稳重,还足以在自家的代码中见到下列代码

// 此处通过这种方式将html插入,是因为博客园自动屏蔽了canvas标签和download属性
var initHtmlConstruct = function () {
  $('#canvas-container').text('').append('<canvas id="target_canvas" width="100" height="100">浏览器不支持此功能,请升级</canvas>')
  $('#toolbar').append('<a class="btn" id="download_file" href="#" download="水印图片">下载合成图片</a>');
}

有关原因注释里也写了,是因为微博的编排器屏蔽了canvas标签和download属性。

有几许要证澳优(Ausnutria Hyproca)下,canvas to base64 png 的话,size 是充足大的, 比源文件还要大的多,所以png 格式是不能够透过canvas做缩减的. (要是作者错了,请报告自个儿)

前言

想给本身的一些图形加上水印,于是就捣腾了那样个东西。

此作用未有虚构宽容性(太懒了),只在Chrome下测量检验通过,纵然您在什么样IE火狐下测量试验不通过就绝不作弄了。

因为使用了download属性,所以IE什么的就绝不指望了,若是您是火狐浏览器的话,本身改一下包容性应该是没难题的。

代码什么的开了F12和好拿呢,未有压缩哦。(最终戏弄一下,本来代码是贴进博客里面包车型地铁,保存为草稿预览的时候也足以,结果在布告后js代码全被遮挡了,最后只能写到页脚里了。所以获得js代码到页脚这里拿走就好了)

自然你也足以访谈下边这么些github地址获替代码:代码地址。

其余为了弄进天涯论坛,特意把代码从ES2014改成了ES5,所以多多少稀少一些乱,可是要求的注明都抬高去了,这么麻烦,点个赞啊。

有关要改水印样式什么的,调整台里改动那个变量的习性就能够。

var watermarkInfo = {
  fontSize: 18, // 像素值
  fontFamily: 'cursive',
  content: '',
  color: '#fffbf0'
};

 废话就十分的少说了,直接上创作。

选择背景图后,设置水印文字,然后拖动水印文字到猖狂地方,最终点击下载文件按键就可以。

选用背景图 安装水印

 

过多门类大家必要上传文件。

总结

看来,那实则是叁个十分的小的成效,可是要把它做得好用一点,涉及到的知识点并不菲,也不并不止笔者关系的那点(比方canvas的反射率样式而不是用图片哦,而是用css样式,照旧从《css揭秘》那本书上学到的)。

理之当然那一个东西或多或少照旧有那么一些毛病,也存在部分宽容性上的主题材料,不过对笔者来讲够用就好。

也指望地点介绍的有个别东西对您也可能有收获。

拖动文字加水印

canvas就算也能捕获事件,获取鼠标地方,并促成拖动文字效果,可是落到实处起来太难为。

故而这里运用更简便易行的方案。

当大家设置水印时,直接将文字渲染到canvas上,然后在文字上方安置贰个颜料透明的故事情节为水印文字的span成分。

接下来我们在这里个span成分上加drag事件。

HTML5拖动功用网络一大堆,这里就不讲了。

主要讲一下贯彻思路:

在最早拖动时,重新用图形渲染canvas,使得以前渲染的文字消失。

在甘休拖动时,获取到现实的岗位,再重复将文字渲染进canvas。

此地谈到来轻巧,其实照旧有一对细节,富含css和js的协作,比方文字拖动到分界时的管理格局,又比方说文字拖动到分界现身换行的意况。

再有点其余的小坑点,供给你和睦看代码去体会了。

此地贴出部分代码:

     // 绑定移动水印相关事件
     var bindEvent4DragWatermark = function () {
          $('#watermark').on('dragstart', function (e) {
            var ctx = document.getElementById('target_canvas').getContext('2d');
            ctx.clearRect(0, 0, $('#target_canvas').width(), $('#target_canvas').height());
            ctx.drawImage(img, 0, 0);
            // 显示可拖拽水印
            $(this).addClass('selected');
            watermarkInfo.offsetX = e.originalEvent.offsetX   canvasInfo.left;
            watermarkInfo.offsetY = e.originalEvent.offsetY   canvasInfo.top;
          });
          // 让水印跟着鼠标移动
          $('#watermark').on('drag', function (e) {
            var x = e.originalEvent.pageX;
            var y = e.originalEvent.pageY;
            if (x === 0 && y === 0) {
              return;
            }
            x -= watermarkInfo.offsetX;
            y -= watermarkInfo.offsetY;

            $('#watermark').css('left', x).css('top', y);
          });
          $('#watermark').on('dragend', function (e) {
            // 调整位置,使水印无法超出canvas边界
            var x = e.originalEvent.pageX - watermarkInfo.offsetX;
            var y = e.originalEvent.pageY - watermarkInfo.offsetY;
            if (x < 0) {
              x = 0;
            }
            if (y < 0) {
              y = 0;
            }

            var maxX = canvasInfo.width - watermarkInfo.width;
            var maxY = canvasInfo.height - watermarkInfo.height;
            if (x > maxX) {
              x = maxX;
            }
            if (y > maxY) {
              y = maxY;
            }
            $('#watermark').css('left', x).css('top', y);
            // 拖拽完水印,文本隐藏
            $('#watermark').removeClass('selected');
            setTextIntoCanvas();
          });
          // 让鼠标不显示禁用样式
          $('#canvas-container').on('dragover', function (e) {
            e.preventDefault();
          });
        }

因而日常上大家是对jpeg做缩减, 品质设置成0.92 的话,size 会和源文件同样. 可是0.92实际不是default的安装,default设置会再低一些。

赢得图片

收获图片实际上即使接纳文件上传控件,也正是

<input id="target_file" type="file"/>

但是原始的公文上传控件极欠赏心悦目,所以遮掩此控件,并加了多个新的按键在它前面

<a class="btn" id="btn_select_file" href="jacascript:void(0)">选择背景图</a>
<input id="target_file" type="file" style="display:none" />

而想达成点击选用背景图按键去挑选文件,用以下代码就可以

// 按下选择的背景图
$('#btn_select_file').click(function () {
  $('#target_file').click();
});

选料文件后,文件上传控件会触发change事件,此时能够获得文件。

$('#target_file').change(function (event) {
    var imgFile = event.target.files[0];
    ......
});

若果上传的是 file 不是 base64 的话,能够运用 Blob.webkitSlice() | Blob.slice 

在图片上加水印

看了地方的代码,里面就有一个步骤是将图纸渲染进canvas,实际上大旨职能便是用canvas来给图片加水印。

操作思路正是先将图纸用drawImage渲染进canvas,再在钦赐的地点用fillText渲染文字就可以,并将最终的canvas用

toDataURL

转载为图片数据就可以。

实际的用法能够参照小编的代码,然后查一下canvas的API就能够。

这种在新手看来很难的东西说穿了实际很轻松,这里就不讲了。

 

但是接下去就劳动了,要是是反革命水印,图片上加水印的地方绝对不可以和图表色差太小,要不然很难开采。

据此本着不一样的图纸,水印的职位一定必要可调动。

最开首的方案是给定两个输入框,然后输入地点,接着渲染水印到文本上。

然而这么些方案首先就面前蒙受多少个易用性的标题,作者怎么获得实际的岗位吗,只可以二个一个去试,并非各类顾客都会用截图软件去找地方。

就此这里运用拖动文字的方案。

参考 : 

将最终修改的图片下载下来

前面大家早已讲到了用canvas的toDataURL函数获取最终的图片数据,然后关于下载就供给运用三个HTML5的download属性。

<a class="btn" id="download_file" href="#" download="水印图片">下载合成图片</a>

接下去是安装图片数据的代码

/**
 * 设置canvas图像到下载链接上
 */
function setCanvasImgToDownloadLink() {
  var imgData = document.getElementById('target_canvas').toDataURL();
  $('#download_file').attr('href', imgData);
};
  1. input file add伊夫ntListener change 监听 input file (你要用 drag drop 代替也行)

  2. 上传文件 file upload 学习笔记分分快三计划。上传文件 file upload 学习笔记分分快三计划。收获 file 对象之后你就能够检查 file.name,file.type,file.size 等等了

  3. 本身可以通过 File里德r.readAsDataU牧马人L(file); 来获取三个 base64 string (那一个是针对性图片的管理,如若是txt的话你能够用别的FileReader.readAs...其余)

  4. 把这么些 base64 归入img.src = base64 的话就能够在该地展现图片了

  5. 在张开三个canvas 后,大家能够把地点的那张相片放入 canvas , 修改它的尺码,加水印等等.

  6. canvas.toDataUCRUISERL() 把图像调换回 base64 string.

  7. 经过XMLHttpRequest 上传这么些 base64 string. (XMLHttpRequest 能够监听 process percent)

  8. 后端把 base64 convert to byte 写入 fileStream 就完了了。 

达成进程中的难题与缓慢解决方案

代码什么的就不全尊敬上来了,只是讲一下里头遇到的一些标题与落到实处思路。

这个难点你只怕已经大半理解了,然则为了兼顾全部人,所以依旧会将有些相比轻巧的技艺点也讲一下。

全总达成进度中相见的难点如下

  • 获得图片
  • 将上传文件转变为图片
  • 在图纸上加水印
  • 拖动文字加水印
  • 将最终修改的图片下载下来

要做到以上的具有须求,我们要求广大底层的 API, 举例 File, FileReader, Canvas , XMLHttpRequest , Blob

有大约的 input file, 有供给证实的,有亟待减弱的(img),有亟待分段的(video),有须要经验好(display on local, ajax & percent) 等等

那边本身只会说说有个别完结 file upload 的基本功 API。

 

document.getElementById("file").addEventListener("change", function (e) {
    var files = S.toArray(this.files);
    var file = files[0];               
    var fileReader = new FileReader();

    fileReader.onloadend = function (e) {    
        var img = new Image();
        img.onload = function () {
            //比例要是尺寸
            var MAX_WIDTH = 2560 / 2;
            var canvas = document.getElementById("canvas");                                             
            var context = canvas.getContext("2d");                                         
            var height = this.height * (MAX_WIDTH / this.width);
            canvas.width = MAX_WIDTH;
            canvas.height = height;
            //画图
            //参数就是把img 的x,y,widthLength,heightLength copy 
            //然后 paste to canvas 的 x,y,widthLength,heightLength
            context.drawImage(this, 0, 0, this.width, this.height, 0, 0, MAX_WIDTH, height); 

            var base64 = canvas.toDataURL("image/jpeg", 0.8); //default 会是 png 格式,第2参数是压缩质量 0-1 (png 不可以压缩)
            base64 = base64.replace(/^data:image/(png|jpeg);base64,/, ""); //后端保存的时候不可以有前面这些字,所以在这里先去除

            var http = new XMLHttpRequest();
            var formData = new FormData(); 
            formData.append("file", base64);
            http.open("POST", "//localhost:8054/module/Upload/UploadAjax.ashx", true);
            http.onreadystatechange = function () {
                if (this.readyState == 4) {
                    if (this.status == 200) {
                        var imgSrc = this.responseText;
                    }
                    else if (this.status == 0) { //abort 会"同步"执行这里 

                    }
                    else {
                        log("file upload ajax fail, looping upload stoped. statusCode : "   this.status);
                    }
                }
            }
            http.upload.onprogress = function (e) {
                if (e.lengthComputable) {
                    var percent = parseFloat(e.loaded / e.total * 100).toFixed(0); //八仙                             
                }
            }
            http.send(formData);
        }
        img.src = this.result;
    }
    fileReader.readAsDataURL(file);

}, false);

//upload base64 的处理
string path = context.Server.MapPath(@"~img"   "abc.jpeg");
using (FileStream fs = new FileStream(path, FileMode.Create))
{
    using (BinaryWriter bw = new BinaryWriter(fs))
    {
        byte[] data = Convert.FromBase64String(context.Request.Form["file"]);                    
        bw.Write(data);
        bw.Close();
    }
}
context.Response.ContentType = "text/plain";
context.Response.Write(path);
//update file 的处理
string[] fileKeys = context.Request.Files.AllKeys;
string fileName = "";
foreach (string fileKey in fileKeys)
{
    HttpPostedFile file = context.Request.Files[fileKey];
    string extension = "."   file.ContentType.Substring(6);
    //string extension = file.FileName.Substring(file.FileName.LastIndexOf("."));
    fileName = Guid.NewGuid()   extension;
    file.SaveAs(context.Server.MapPath(@"~img"   fileName));
}
context.Response.ContentType = "text/plain";
context.Response.Write(fileName);

设若要协助分段上传的话,base64应该直接substring记入index position 就足以了。

上边笔者尚未兑现水印和分层,今后等自身临时光写三个整机的控件时,小编才履新。

大旨的步调是这么的

本文由分分快三计划发布,转载请注明来源

关键词: 分分快三计划 HTML5