文件处理-图片

文件图片关系图
图片转换.png

图中的几个对象包括 canvas、image、DataURL、ObjectURL、Blob、ArrayBuffer

  1. 图片获取DataURL
  • dataURL是一种特殊格式的URL。它的前缀是{\color{red}{data}}
// 格式
data:[<mediatype>][,base64],<data>
// eg
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAhAAAAIwCAYAAADXrFK...

从本地选择图片获取DataURL

const reader = new FileReader();
reader.onload = function () {
    const output = document.querySelector("img");
    output.src = reader.result;
};
// 这里传入的参数是一个文件File 而上面图片中是blob。 因为File继承Blob
reader.readAsDataURL(event.target.files[0]);

// 补充  reader.readAsText()  可以获取文本的内容
  1. 图片加载ObjectURL
    通过 URL.createObjectURL(blob)创建
// 格式
blob:null/ab24c171-1c5f-4de1-a44e-568bc1f77d7b
// eg
fetch("https://avatars3.githubusercontent.com/u/4220799")
.then((response) => response.blob())
.then((blob) => {
    const objectURL = URL.createObjectURL(blob);
    image.src = objectURL;
});
// 仅作示例 实际不这么使用

//补充  下载为文件
//  const blob = new Blob([res.data], { type: "application/vnd.ms-excel" });
const link = document.createElement('a');
link.download ='test.excel';
link.style.display = 'none';
link.href = URL.createObjectURL(blob);
document.body.appendChild(link);
link.click();
// 这里需要释放掉,否则会一直占用内存
URL.revokeObjectURL(link.href); // 释放URL 对象
document.body.removeChild(link);
  1. Canvas中的图片处理
  • drawImage(image) 根据已有的图片对象 绘制图片
  • getImageData(x,y, w,h) 获取画布某一个区域内的图像数据(像素数据)
  • putImageData() 将图像数据绘制在画布上
    3.1 图片压缩
1. 绘制图片
context.drawImage(img, dx, dy, dWidth, dHeight)
2. 压缩
const dataUrl = canvas.toDataURL(mimeType, qualityArgument);
const blob = canvas.toBlob(callback, mimeType, qualityArgument)

3.2 图片灰度化

1 获取图像的像素数据
const imageData = ctx.getImageData(x, y, W, H);
const data = imageData.data;
2. 处理图像的像素数据
for (let i = 0; i < data.length; i += 4) {
    const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
    data[i] = avg; // red
    data[i + 1] = avg; // green
    data[i + 2] = avg; // blue
}
3. 处理后的数据重新绘制
ctx.putImageData(imageData, x, y);

3.3 图片打码

1. 获取图像的像素
const imageData = ctx.getImageData(x, y, w, h).data;
// option defaults
2. 设置马赛克块的像素大小 
const res = 4
const size = res
const alpha = 1
const cols = w / res + 1
const rows = h / res + 1
const halfSize = size / 2
3. 双循环行和列
for (let row = 0; row < rows; row++) {
    let y = (row - 0.5) * res
    // normalize y so shapes around edges get color
    let pixelY = Math.max(Math.min(y, h - 1), 0)

    for (let col = 0; col < cols; col++) {
        let x = (col - 0.5) * res
        // normalize y so shapes around edges get color
        let pixelX = Math.max(Math.min(x, w - 1), 0)
        let pixelIndex = (pixelX + pixelY * w) * 4
        const red = imageData[pixelIndex + 0]
        const green = imageData[pixelIndex + 1]
        const blue = imageData[pixelIndex + 2]
        const pixelAlpha = alpha * (imageData[pixelIndex + 3] / 255)
        4 绘制马赛克方块  square
        ctx.fillStyle = `rgba(${red},${green},${blue},${pixelAlpha})`
        ctx.fillRect(x - halfSize, y - halfSize, size, size)
    } // col
} // row

3.4 取色器

1. 获取位置
const {x, y} = event;
2. 获取位置后的一个像素
const imageData = ctx.getImageData(x, y, 1, 1).data;
const colorValue = imageData.join(',');
const colorValueEl = document.querySelector('#colorValue');
colorValueEl.innerText = colorValue;

const bgColorEl = document.querySelector('#bgColor');
bgColorEl.style.backgroundColor = `rgba(${colorValue})`

3.4 边缘检测

1. 像素黑白化
const grayData = blackWhitePixel(imageData);
2. 检测边缘
const edgeData = contourDIB(grayData, w, h);
_imageData.data = imageData;
ctx.putImageData(_imageData, 0, 0);

function contourDIB(data, lWidth, lHeight) {
    // 保存原始数据
    const dataInit = [];
    for (let i = 0, len = data.length; i < len; i++) {
        dataInit[i] = data[i];
    }
    for (let j = 1; j < lHeight - 1; j++) {
        for (let i = 1; i < lWidth - 1; i++) {
            const lpSrc = j * lWidth + i;
            const pixel = dataInit[lpSrc * 4];
            if (pixel === 0) {
                const surroundArr = [lpSrc + lWidth - 1, lpSrc + lWidth,
                lpSrc + lWidth + 1, lpSrc - 1, lpSrc + 1,
                lpSrc - lWidth - 1, lpSrc - lWidth, lpSrc - lWidth + 1];
                let value = 0;
                for (let m = 0, len = surroundArr.length; m < len; m++) {
                    value += dataInit[surroundArr[m] * 4];
                }
                // 如果相邻对八个点都是黑点 说明不是边缘
                if (value === 0) {
                    for (let k = 0; k < 3; k++) {
                        data[lpSrc * 4 + k] = 255;
                    }
                }
            }
        }
    }
    return data
}

参考
玩转前端二进制
数字图像处理-前端实现

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容