Skip to main content

cpsImg

/*
* @Author: Administrator
* @Date: 2020-07-13 08:57:12
* @Last Modified by: CPS
* @Last Modified time: 2020-11-21 09:19:06
* 修改自网上的某个读取jpg的库
* 修正了通过buffer读取bmp的时候,格式不是uin32array的问题
* 修正 jpg头部支取前3个头部信息,原来取4个,有些jpg会不识别
*/

// 设置图片信息对应的内存记录地址
// 对应各个格式的文件头,识别格式
var IMAGE_HEAD_SIGS = {
GIF: [0x47, 0x49, 0x46], //'G' 'I' 'F' ascii
PNG: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a],
JPG: [0xff, 0xd8, 0xff],
BMP: [0x42, 0x4d],
};

function readUint32BE(bytes, start) {
var uarr = new Uint32Array(1);
uarr[0] = (bytes[start + 0] & 0xff) << 24;
uarr[0] = uarr[0] | ((bytes[start + 1] & 0xff) << 16);
uarr[0] = uarr[0] | ((bytes[start + 2] & 0xff) << 8);
uarr[0] = uarr[0] | (bytes[start + 3] & 0xff);
return uarr[0];
}

function readUint16BE(bytes, start) {
var uarr = new Uint32Array(1);
uarr[0] = (bytes[start + 0] & 0xff) << 8;
uarr[0] = uarr[0] | (bytes[start + 1] & 0xff);
return uarr[0];
}

//LE [0x01,0x02,0x03,0x04] -> 0x04030201
function readUint32LE(bytes, start) {
var uarr = new Uint32Array(1);
uarr[0] = (bytes[start + 3] & 0xff) << 24;
uarr[0] = uarr[0] | ((bytes[start + 2] & 0xff) << 16);
uarr[0] = uarr[0] | ((bytes[start + 1] & 0xff) << 8);
uarr[0] = uarr[0] | (bytes[start + 0] & 0xff);
return uarr[0];
}

function readUint16LE(bytes, start) {
var uarr = new Uint32Array(1);
uarr[0] = (bytes[start + 1] & 0xff) << 8;
uarr[0] = uarr[0] | (bytes[start + 0] & 0xff);
return uarr[0];
}

function ReadPNG(bytes) {
//获取文件头特征
let h = new Uint8Array(bytes.slice(0, 8));

// 将特征与设置好的进行比较
if (h.toString() === IMAGE_HEAD_SIGS.PNG.toString()) {
console.log("ReadPNG2");

let width = readUint32BE(bytes, 16);
let height = readUint32BE(bytes, 20);
return {
width,
height,
};
}
}

function ReadJPG(bytes) {
//获取文件头特征
let h = new Uint8Array(bytes.slice(0, 3));

console.log("ReadPNG3", h);
console.log("ReadPNG3", h.toString());
console.log("ReadPNG3", IMAGE_HEAD_SIGS.JPG.toString());

if (h.toString() === IMAGE_HEAD_SIGS.JPG.toString()) {
const M_SOF0 = 0xc0; /* Start Of Frame N */
const M_SOF1 = 0xc1; /* N indicates which compression process */
const M_SOF2 = 0xc2; /* Only SOF0-SOF2 are now in common use */
const M_SOF3 = 0xc3;
const M_SOF5 = 0xc5; /* NB: codes C4 and CC are NOT SOF markers */
const M_SOF6 = 0xc6;
const M_SOF7 = 0xc7;
const M_SOF9 = 0xc9;
const M_SOF10 = 0xca;
const M_SOF11 = 0xcb;
const M_SOF13 = 0xcd;
const M_SOF14 = 0xce;
const M_SOF15 = 0xcf;
for (let i = 0; i < bytes.length; i++) {
if (bytes[i] === 0xff) {
switch (bytes[i + 1]) {
case M_SOF0:
case M_SOF1:
case M_SOF2:
case M_SOF3:
case M_SOF5:
case M_SOF6:
case M_SOF7:
case M_SOF9:
case M_SOF10:
case M_SOF11:
case M_SOF13:
case M_SOF14:
case M_SOF15: {
//高在前,宽在后。
let width = readUint16BE(bytes, i + 7);
let height = readUint16BE(bytes, i + 5);
return {
width,
height,
};
}
default:
break;
}
}
}
}
}

function ReadGIF(bytes) {
if (bytes.slice(0, 3).toString() === IMAGE_HEAD_SIGS.GIF.toString()) {
let width = readUint16LE(bytes, 6);
let height = readUint16LE(bytes, 8);
return {
width,
height,
};
}
}

function ReadBMP(bytes) {
// 主要修改了这里
//获取文件头特征
let h = new Uint8Array(bytes.slice(0, 2));

if (h.toString() === IMAGE_HEAD_SIGS.BMP.toString()) {
//虽然格式为4字节,这里只取2字节,确保height为正数。为负数时,图像为倒置图像。
let height = readUint16LE(bytes, 22);
let width = readUint16LE(bytes, 18);
return {
width,
height,
};
}
}

function base64ToBytes(base64) {
let baseSplit = base64.split(",");
// let mime = arr[0].match(/:(.*?);/)[1] || type;
// 去掉url的头,并转化为byte
let strArray = window.atob(baseSplit[1]);
// 处理异常,将ascii码小于0的转换为大于0
let buffer = new ArrayBuffer(strArray.length);
let bytes = new Uint8Array(buffer);
for (let i = 0; i < strArray.length; i++) {
bytes[i] = strArray.charCodeAt(i);
}
return bytes;
}

function ReadPNGBase64(base64) {
return ReadPNG(base64ToBytes(base64));
}

function ReadJPGBase64(base64) {
return ReadJPG(base64ToBytes(base64));
}

function ReadGIFBase64(base64) {
return ReadGIF(base64ToBytes(base64));
}

function ReadBMPBase64(base64) {
return ReadBMP(base64ToBytes(base64));
}

function ReadBase64Dimension(base64, extType) {
switch (extType) {
case "png":
return ReadPNGBase64(base64);
case "jpg":
case "jpeg":
return ReadJPGBase64(base64);
case "gif":
return ReadGIFBase64(base64);
case "bmp":
return ReadBMPBase64(base64);
default:
return undefined;
}
}

class cpsImg {
constructor() {
this.data = {
png: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a].toString(),
jpg: [0xff, 0xd8, 0xff, 0xe0].toString(),
git: [0x47, 0x49, 0x46].toString(),
bmp: [0x42, 0x4d].toString(),
};
}

getExt(filename, callback) {
fs.readFile(filename, (err, bytes) => {
if (err) {
console.log(err);
} else {
let h = new Uint8Array(bytes.slice(0, 8));
for (let each of this.data) {
if (each.head == h.slice(0, each.byte)) {
console.log("当前的格式识别为:" + each.ext);
}
}
}
});
}

pngSize(bytes) {
//获取文件头特征
let h = new Uint8Array(bytes.slice(0, 8));

console.log(h);
// 将特征与设置好的进行比较
console.log(h.toString());
if (h.toString() === this.data.png) {
let width = readUint32BE(bytes, 16); //读取高宽位置的值
let height = readUint32BE(bytes, 20); //读取高宽位置的值
return {
type: "png",
width,
height,
};
}
}
}

// node环境 测试
if (require.main === module) {
const fs = require("fs");
let tar = fs.readFileSync("D:/User/桌面/ccvbb.png");

res = ReadPNG(tar);
console.log("res: ", res);
}

module.exports = {
ReadPNG,
ReadJPG,
ReadGIF,
ReadBMP,
ReadPNGBase64,
ReadJPGBase64,
ReadGIFBase64,
ReadBMPBase64,
ReadBase64Dimension,
};

获取img标签文件二进制

/**
* 图像转Base64
*/
function getBase64Image(img) {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
var dataURL = canvas.toDataURL("image/" + ext);
return dataURL;
}