import { IMAGE_TYPE } from "./enum"; /** * 检测空图片 * @param img * @returns */ export function checkEmptyImg(img: HTMLImageElement) { // 创建一个 Canvas 元素 const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); if (!ctx) { return; } // 设置 Canvas 的宽度和高度与图片一致 canvas.width = img.width; canvas.height = img.height; // 将图片绘制到Canvas上 ctx.drawImage(img, 0, 0); // 获取Canvas中的像素数据 const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; // 判断从左上角到右下角的像素是否都是黑色 let topLeftToBottomRight = true; const iUp = 0; const redUp = data[iUp]; const greenUp = data[iUp + 1]; const blueUp = data[iUp + 2]; const alphaUp = data[iUp + 3]; for (let i = 0; i < data.length; i += 4) { const red = data[i]; const green = data[i + 1]; const blue = data[i + 2]; const alpha = data[i + 3]; if (red !== redUp || green !== greenUp || blue !== blueUp || alpha !== alphaUp) { topLeftToBottomRight = false; break; } } // 判断从右上角到左下角的像素是否都是黑色 let topRightToBottomLeft = true; const jDown = data.length - 4; const redDown = data[jDown]; const greenDown = data[jDown + 1]; const blueDown = data[jDown + 2]; const alphaDown = data[jDown + 3]; for (let j = jDown; j >= 0; j -= 4) { const red = data[j]; const green = data[j + 1]; const blue = data[j + 2]; const alpha = data[j + 3]; if (red !== redDown || green !== greenDown || blue !== blueDown || alpha !== alphaDown) { topRightToBottomLeft = false; break; } } // 打印结果 if (topLeftToBottomRight && topRightToBottomLeft) { return false; } else { return true; } } /** * 获取dom元素宽高 * @param d dom元素 * @returns {{width: number, height: number}} */ export function getDomWH(d: HTMLElement | HTMLImageElement | HTMLCanvasElement) { if (d instanceof Image || d instanceof HTMLCanvasElement) { return { width: d.width || d.offsetWidth, height: d.height || d.offsetHeight, }; } return { width: d.offsetWidth, height: d.offsetHeight, }; } /** * 设置dom元素宽高 * @param d dom元素 * @param w 宽 * @param h 高 */ export function setDomWH(dom: HTMLElement, w: number, h: number) { dom.setAttribute("width", `${w}`); dom.setAttribute("height", `${h}`); } /** * 获取当前canvas图片Blob对象 * @param canvas * @returns {Promise} */ export function getCanvasPic(canvas: HTMLCanvasElement): Blob { var gl = canvas.getContext("2d", { preserveDrawingBuffer: true }); return dataURItoBlob(canvas.toDataURL(IMAGE_TYPE.PNG, 1)); } /** * base64 字符串转 blob * @param base64 * @returns */ export function dataURItoBlob(base64: string): Blob { let arr = base64.split(","); let mime = arr[0]?.match(/:(.*?);/)?.[1]; let bstr = atob(arr[1]); let n = bstr.length; let u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); } /** * 获取图片元素 * @param imgSrc * @returns */ export function getImgEle(imgSrc: string): Promise { return new Promise((resolve) => { const img = new Image(); img.onload = function () { resolve(img); }; img.src = imgSrc; }); } /** * 获取图片 Base64 字符串 * @param imgSrc * @returns */ export function getImgBase64(imgSrc: string): Promise { return getImgEle(imgSrc).then((img) => { const canvas = document.createElement("canvas"); let { width, height } = getDomWH(img); setDomWH(canvas, width, height); const ctx = canvas.getContext("2d"); ctx && ctx.drawImage(img, 0, 0, width, height, 0, 0, width, height); return canvas.toDataURL(IMAGE_TYPE.PNG, 1); }); } /** * 通过图片地址获取对应 canvas * @param imgSrc * @returns */ export function getCanvas(imgSrc: string): Promise { return getImgEle(imgSrc).then((img) => { const canvas = document.createElement("canvas"); let { width, height } = getDomWH(img); setDomWH(canvas, width, height); const ctx = canvas.getContext("2d"); ctx && ctx.drawImage(img, 0, 0, width, height, 0, 0, width, height); return canvas; }); } /** * 通过图片地址获取对应 canvas * @param img * @returns */ export function getCanvasByImg(img: HTMLImageElement): HTMLCanvasElement { const canvas = document.createElement("canvas"); let { width, height } = getDomWH(img); setDomWH(canvas, width, height); const ctx = canvas.getContext("2d"); ctx && ctx.drawImage(img, 0, 0, width, height, 0, 0, width, height); return canvas; } /** * 截取图片 * @param img * @param opt * @param opt.startX * @param opt.startY * @param opt.width * @param opt.height * @returns Promise */ export function cropImage( img: HTMLImageElement | HTMLCanvasElement, opt: { startX: number; startY: number; width: number; height: number }, ) { return cropImageToCanvas(img, opt).toDataURL(IMAGE_TYPE.PNG, 1); } /** * 截取图片 * @param img * @param opt * @param opt.startX * @param opt.startY * @param opt.width * @param opt.height * @returns Promise */ export function cropImageToCanvas( img: HTMLImageElement | HTMLCanvasElement, opt: { startX: number; startY: number; width: number; height: number }, ) { const { startX, startY, width, height } = opt; const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); // 设置 canvas 的宽度和高度为裁剪后的尺寸 canvas.width = width; // 裁剪后的宽度 canvas.height = height; // 裁剪后的高度 // 在 canvas 上绘制裁剪后的图像 ctx?.drawImage(img, startX, startY, width, height, 0, 0, width, height); // 可以将裁剪后的图像数据获取出来 return canvas; } /** * 截取图片 * @param img * @param opt * @param opt.startX * @param opt.startY * @param opt.width * @param opt.height * @returns Promise */ export function imgToCanvas(img: HTMLImageElement) { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = img.width; canvas.height = img.height; ctx?.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); return canvas; } /** * 缩放图片 * @param img * @param opt * @returns */ export function scaleImage(img: HTMLImageElement | HTMLCanvasElement, opt = { scaleFactor: 1 }) { return scaleImageToCanvas(img, opt).toDataURL(IMAGE_TYPE.PNG, 1); } /** * 缩放图片 * @param img * @param opt * @returns */ export function scaleImageToCanvas(img: HTMLImageElement | HTMLCanvasElement, opt = { scaleFactor: 1 }) { const { scaleFactor = 1 } = opt; const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = img.width * scaleFactor; canvas.height = img.height * scaleFactor; ctx?.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); return canvas; } /** * 图片转为 base64 * @param img * @returns */ export async function imgToBase64(img: string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement) { if (!img || img instanceof Blob) { return img; } let _img = img; if (img instanceof Image) { _img = img.src; } else if (img instanceof HTMLVideoElement) { // 从视频中获取图片 const canvas = document.createElement("canvas"); let { width, height } = getDomWH(img); setDomWH(canvas, width, height); const ctx = canvas.getContext("2d"); ctx && ctx.drawImage(img, 0, 0, width, height, 0, 0, width, height); _img = canvas.toDataURL(IMAGE_TYPE.PNG, 1); } else if (img instanceof HTMLCanvasElement) { _img = img.toDataURL(IMAGE_TYPE.PNG, 1); } else if (typeof _img === "string" && !_img.startsWith("data:image/")) { // 加载图片,并获取图片 base64 _img = await getImgBase64(_img); } return _img; } /** * 图片转为 Blob * @param img * @returns */ export async function imgToBlob(img: string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement): Promise { if (!img) { throw new Error("请传入图片数据"); } if (img instanceof Blob) { return Promise.resolve(img); } const _img = await imgToBase64(img); if (typeof _img !== "string") { throw new Error("传入的图片数据不正确"); } return dataURItoBlob(_img); } /** * 获取图片的 base64、blob 格式 * @param img */ export async function getAllTypeImg(img: string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement) { const base64 = await imgToBase64(img); return { base64, blob: typeof base64 === "string" && dataURItoBlob(base64), }; }