js文件操作总结一:图片篇

栏目: Html5 · 发布时间: 5年前

内容简介:html部分js获取文件html部分可以是一个div元素就行
  • 文件上传
  • 图片编辑
  • 图片文件下载

一、文件上传

文件上传目前了解的主要有三种方式:

  • type="file"的input输入框
  • drop拖放事件;
  • 另有"ctrl+V"进行粘贴,但是此方法使用有局限性,如:不支持windows系统文件的复制粘贴(大概理解为windows系统的粘贴只是对文件路径的引用)

1、input文件上传

html部分

<input id="fileInput" type="file" accept="image/png, image/jpeg">
// accept定义支持的文件类型
复制代码

js获取文件

$('#fileInput').on('change', function () {
    fn(this.files[0]);
})
// this.files是一个文件集合,如果一次性上传多个文件相应就是this.files[0]、this.files[1]...
复制代码

2、drop拖放文件上传

html部分可以是一个div元素就行

<div class="dropBox" id="dropHere">
    <p class="info">把文件拖放到这里</p>
    <p class="info hide">你上传的文件是:<span id="fileName"></span></p>
</div>
复制代码

js操作部分需要对目标元素的ondragenter和ondragover进行阻止默认事件操作,防止浏览器直接打开文件

// 拖拽上传事件
function bandDropEvent (el,fn) {
    el.ondragenter = function (event) {   // 清除默认事件,防止浏览器直接打开图片文件
        event.stopPropagation();
        event.preventDefault();
    };
    el.ondragover = function (event) {   // 清除默认事件,防止浏览器直接打开图片文件
        event.stopPropagation();
        event.preventDefault();
    };
    el.ondrop = function (event) {
        event.stopPropagation();
        event.preventDefault();
        fn(event.dataTransfer.files[0]);
    };
}
复制代码

更好的做法是在div里再放一个type='file'的input,然后绑定点击div事件触发input的点击事件,这样就可以同时支持点击及拖放上传

这里是一个demo

二、图片编辑

解决完文件上传之后,接着就需要对文件数据进行操作啦!首先我们拿图片文件来练手,这里我们分几个步骤:

1、图片预览实现

首先需要了解一个API:FileReader;

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。 ---来自MDN

直接上代码

function file2url(file, fn) {
    const reader = new FileReader();
    reader.addEventListener('load', function () {
        const src = reader.result;
        fn(src);
    }, false);
    reader.readAsDataURL(file);
}
复制代码
  • 1、首先我们初始化一个 FileReader 的实例 reader ;
  • 2、然后我们监听实例 readerload 事件,将 reader.result 中包含的数据保存到变量 src
  • 3、最后我们调用 reader.readAsDataURL() 方法处理目标文件 file

通过 FileReader.readAsDataURL() 方法,我们可以成功将图片文件转换成一串以 URL格式的字符串 (base64编码)表示所读取文件的内容(FileReader还可以将文件转换成文本格式,此处先不涉及),我们可以将转换后的url赋值给img元素的src属性,这样就可以查看图片预览了

fileInput.addEventListener('change', function () {
    showFileName(this.files[0]);
    file2url(this.files[0], function (src) {
        document.querySelectorAll('img')[0].src = src;
    })
});
复制代码

稍微修改一下上一步的demo,让它实现图片预览的功能,点击这里查看

2、图片编辑

熟悉PS的肯定知道,在位图里整张图片由N多的像素点组成,每一个小的像素点可以想象成一个小的色块,N多色块拼接在一起就成了我们最终看到的图片,如果能操作每个像素点的色值,就能够对图片进行编辑了,我们开始吧:

首先还是 一个 几个API: (一个个介绍有点长,请自行点击链接去查看相关信息)

试着用这几个API将图片反色,主要代码如下:

// 将图片反色
function inverse(src) {
    const img = new Image,
        canvas = document.createElement('canvas'),
        ctx = canvas.getContext('2d');
    let w,h,data;
    img.src = src;
    const imgLoad = new Promise((resolve, reject) => {
        img.onload = function () {
            w = this.width;
            h = this.height;
            canvas.width = w;
            canvas.height = h;
            ctx.drawImage(this, 0, 0, w, h);
            data = ctx.getImageData(0, 0, w, h);
            const obj = {
                data: data,
                width: w,
                height: h
            };
            resolve(obj);
        };
    });
    // 改变图片像素
    imgLoad.then((val) => {
        return new Promise((resolve, reject) => {
            let imgData = val.data.data;
            let w = val.width;
            let h = val.height;
            for(let i = 0; i < h; i++) {        // 遍历像素点
                for(let j = 0; j < w; j++) {
                    let x = i * 4 * w + 4 * j;
                    imgData[x] = 255 - imgData[x];
                    imgData[x + 1] = 255 - imgData[x + 1];
                    imgData[x + 2] = 255 - imgData[x + 2];
                }
            }
            ctx.putImageData(data, 0, 0);
            resolve(canvas.toDataURL("image/jpeg", 1));
        });
    }).then(function (url) {
        document.querySelector('.showNewImg').src = url;
    });
}
复制代码

需要注意的地方:

  • 文件的操作是异步进行的,此处用了Promise;
  • 对像素点的处理用到了嵌套的循环,外层循环X轴,内层循环Y轴上与之交叉的像素点,每一个像素点由4个数据表示,分别对应RGBA;

因此R值的下标为:X轴序号 * 4 * 图片宽度 + Y轴序号 * 4

G值的下标为R值下标+1,B值的下标为R值下标+2,A值的下标为R值下标+3

将图片反色的demo,点击这里查看。

编辑后的图片文件下载

下载的实现这里用到的是a标签的download属性;

主要代码如下:

function download(url, fileName) {
    const link = document.createElement('a');
    link.href = url;
    link.download = fileName;
    link.click();
}
复制代码

增加下载功能的demo,点击这里查看。

总结

  • 图片的操作还能实现很多其他的效果,贴一个之前写的二维码图片合成页面,这个页面写的比较早,代码有点乱,不过本篇内容出自对该页面的梳理;

  • 接下来还会继续整理,dom转换图片,.html文件编辑等其他文件相关操作;

  • PS:本篇主要对图片的操作做了个简单的总结,代码的实现并没有考虑兼容等(最喜欢写demo这种无拘无束放飞自我的感觉),限于作者能力有限,相关代码仅作示范,如有不足,烦请告知,谢谢


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Series 60 应用程序开发

Series 60 应用程序开发

巴克 / 人民邮电出版社 / 2005-7 / 75.0

Series 60智能手机开发平台正掀起新一轮的移动服务浪潮。超过60%的手机生产商获得了Series 60平台的授权。Series 60移动应用开发平台拥有最大的用户群,从而成为智能手机市场的代表。诺基亚与EMCC软件公司合作,为C++程序员和软件设计师编撰了这本Series 60开发的权威指南。本书由诺基亚资深专家进行了全面审阅。本书内容涉及了开发过程的各个阶段,从设计、编程、测试、调试到部署......一起来看看 《Series 60 应用程序开发》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码