canvas画板绘制多图和绘制文字及下载

**

canvas画板绘制多图和绘制文字及下载

有要求需要做宣传图,加文字动态排版,以及,二维码排版,还要完成后下载的功能,然后研究了一下午,写了一个供大家学习

上效果图
在这里插入图片描述
上代码:

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
	</head>

	<body>
		<div id="app">
			<template>
				<canvas id="canvasone" width="500" height="800" style="border:1px solid #d3d3d3;"></canvas>
				<button @click="downloads">下载图片</button>
			</template>
		</div>
	</body>
	<script type="text/javascript" src="canvas2image.js"></script>
	<script src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/element-ui/lib/index.js"></script>
	<script>
		new Vue({
			el: '#app',
			data: function() {
				return {
					name: "刘亦菲",
					age: "1987.8.25",
					resume: "刘亦菲,中国著名女演员、歌手。1987年8月25日出生于武汉,现居北京。其父是大学教授,母亲是国家一级舞蹈演员,10岁时父母离异随母亲远赴美国定居。2002年回到北京,通过英语及专业考试被北京电影学院破格录取,并于同年被制片人游建鸣发掘出演《金粉世家》。其后又被著名制片人张纪中选中,出演《天龙八部》中的王语嫣和《神雕侠侣》中的小龙女而红遍亚洲,刘亦菲的清纯玉女形象深入人心,并成功跻身当红女星的行列。"
				}
			},
			mounted() {
				this.show();
			},
			methods: {
				show() {
					var that=this;
					var c = document.getElementById("canvasone");
					var ctx = c.getContext("2d");
					var canvasImageArr = [
						'https://img2.baidu.com/it/u=1735401672,3210155832&fm=26&fmt=auto&gp=0.jpg',
						'https://img1.baidu.com/it/u=318258528,1264863502&fm=26&fmt=auto&gp=0.jpg'
					];

					for(let i = 0; i < canvasImageArr.length; i++) {
						let img = new Image();
						img.src = canvasImageArr[i];
						img.setAttribute('crossOrigin', 'anonymous');
						if(i == 0) {
							new Promise((resolve, reject) => {
								img.onload = function() {
									ctx.drawImage(img, 0, 0, 500, 800);
									ctx.fillStyle = "#FF0000";
									ctx.font = "30px Arial";
									//	ctx.fillText("刘亦菲", 20, 750);
                                    //竖着排版
									for(let i = 0; i < that.name.length; i++) {
										ctx.fillText(that.name.substring(i, i + 1), 20, 60 + (i * 30));
									}
									for(let i = 0; i < that.age.length; i++) {
										ctx.font = "18px Arial";
										ctx.fillText(that.age.substring(i, i + 1), 60, 80 + (i * 18));
									}
                                    //30字一行
									for(let i = 0; i < (that.resume.length)/30; i++) {
										ctx.fillStyle = "#00FFFF";
										ctx.font = "14px Arial";
										let s=i*30;
										ctx.fillText(that.resume.substring(s,s+30), 20, 650 + (i * 18),300);
									}

									resolve(img);
								};
							});
						} else if(i == 1) {
							new Promise((resolve, reject) => {
								img.onload = function() {
									ctx.drawImage(img, 350, 650, 100, 100);
									resolve(img);
								};
							});
						}
						console.log(img.src)
					}
				},
				//下载
				downloads() {
					var oCanvas = document.getElementById("canvasone");
                    //下边想要什么格式就用哪一个
					Canvas2Image.saveAsPNG(oCanvas); // 这将会提示用户保存PNG图片

					//Canvas2Image.saveAsJPEG(oCanvas); // 这将会提示用户保存JPG图片

					//Canvas2Image.saveAsBMP(oCanvas); // 这将会提示用户保存BMP图片

					// 返回一个包含PNG图片的<img>元素
					//var oImgPNG = Canvas2Image.saveAsPNG(oCanvas, true);

					// 返回一个包含JPG图片的<img>元素
					//var oImgJPEG = Canvas2Image.saveAsJPEG(oCanvas, true);

					// 返回一个包含BMP图片的<img>元素
					//var oImgBMP = Canvas2Image.saveAsBMP(oCanvas, true);

					// 这些函数都可以接受高度和宽度的参数
					// 可以用来调整图片大小

					// 把画布保存成100x100的png格式
					//Canvas2Image.saveAsPNG(oCanvas, false, 100, 100);
				}
			},

		})
	</script>

</html>

Canvas2Image.js这个需要单独引入,这里我也给文件附上,使用时,新建canvas2image.js,然后把代码贴进canvas2image.js就可以使用了,然后在使用的地方引入

/**
 * covert canvas to image
 * and save the image file
 */
 const Canvas2Image = (function () {
    // check if support sth.
    const $support = (function () {
        const canvas = document.createElement("canvas"),
            ctx = canvas.getContext("2d");

        return {
            canvas: !!ctx,
            imageData: !!ctx.getImageData,
            dataURL: !!canvas.toDataURL,
            btoa: !!window.btoa,
        };
    })();

    const downloadMime = "image/octet-stream";

    function scaleCanvas(canvas, width, height) {
        const w = canvas.width,
            h = canvas.height;
        if (width === undefined) {
            width = w;
        }
        if (height === undefined) {
            height = h;
        }

        let retCanvas = document.createElement("canvas");
        let retCtx = retCanvas.getContext("2d");
        retCanvas.width = width;
        retCanvas.height = height;
        retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
        return retCanvas;
    }

    function getDataURL(canvas, type, width, height) {
        canvas = scaleCanvas(canvas, width, height);
        return canvas.toDataURL(type);
    }

    // save file to local with file name and file type
    function saveFile(strData, fileType, fileName = "name") {
        // document.location.href = strData;
        let saveLink = document.createElement("a");
        // download file name
        saveLink.download = fileName + "." + fileType;
        // download file data
        saveLink.href = strData;
        // start download
        saveLink.click();
    }

    function genImage(strData) {
        let img = document.createElement("img");
        img.src = strData;
        return img;
    }

    function fixType(type) {
        type = type.toLowerCase().replace(/jpg/i, "jpeg");
        const r = type.match(/png|jpeg|bmp|gif/)[0];
        return "image/" + r;
    }

    function encodeData(data) {
        if (!window.btoa) {
            // eslint-disable-next-line no-throw-literal
            throw "btoa undefined";
        }
        let str = "";
        if (typeof data == "string") {
            str = data;
        } else {
            for (let i = 0; i < data.length; i++) {
                str += String.fromCharCode(data[i]);
            }
        }

        return btoa(str);
    }

    function getImageData(canvas) {
        const w = canvas.width,
            h = canvas.height;
        return canvas.getContext("2d").getImageData(0, 0, w, h);
    }

    function makeURI(strData, type) {
        return "data:" + type + ";base64," + strData;
    }

    /**
     * create bitmap image
     * 按照规则生成图片响应头和响应体
     */
    const genBitmapImage = function (oData) {
        //
        // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
        // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
        //

        const biWidth = oData.width;
        const biHeight = oData.height;
        const biSizeImage = biWidth * biHeight * 3;
        const bfSize = biSizeImage + 54; // total header size = 54 bytes

        //
        //  typedef struct tagBITMAPFILEHEADER {
        //  	WORD bfType;
        //  	DWORD bfSize;
        //  	WORD bfReserved1;
        //  	WORD bfReserved2;
        //  	DWORD bfOffBits;
        //  } BITMAPFILEHEADER;
        //
        const BITMAPFILEHEADER = [
            // WORD bfType -- The file type signature; must be "BM"
            0x42,
            0x4d,
            // DWORD bfSize -- The size, in bytes, of the bitmap file
            bfSize & 0xff,
            (bfSize >> 8) & 0xff,
            (bfSize >> 16) & 0xff,
            (bfSize >> 24) & 0xff,
            // WORD bfReserved1 -- Reserved; must be zero
            0,
            0,
            // WORD bfReserved2 -- Reserved; must be zero
            0,
            0,
            // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
            54,
            0,
            0,
            0,
        ];

        //
        //  typedef struct tagBITMAPINFOHEADER {
        //  	DWORD biSize;
        //  	LONG  biWidth;
        //  	LONG  biHeight;
        //  	WORD  biPlanes;
        //  	WORD  biBitCount;
        //  	DWORD biCompression;
        //  	DWORD biSizeImage;
        //  	LONG  biXPelsPerMeter;
        //  	LONG  biYPelsPerMeter;
        //  	DWORD biClrUsed;
        //  	DWORD biClrImportant;
        //  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
        //
        const BITMAPINFOHEADER = [
            // DWORD biSize -- The number of bytes required by the structure
            40,
            0,
            0,
            0,
            // LONG biWidth -- The width of the bitmap, in pixels
            biWidth & 0xff,
            (biWidth >> 8) & 0xff,
            (biWidth >> 16) & 0xff,
            (biWidth >> 24) & 0xff,
            // LONG biHeight -- The height of the bitmap, in pixels
            biHeight & 0xff,
            (biHeight >> 8) & 0xff,
            (biHeight >> 16) & 0xff,
            (biHeight >> 24) & 0xff,
            // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
            1,
            0,
            // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
            // has a maximum of 2^24 colors (16777216, Truecolor)
            24,
            0,
            // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
            0,
            0,
            0,
            0,
            // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
            biSizeImage & 0xff,
            (biSizeImage >> 8) & 0xff,
            (biSizeImage >> 16) & 0xff,
            (biSizeImage >> 24) & 0xff,
            // LONG biXPelsPerMeter, unused
            0,
            0,
            0,
            0,
            // LONG biYPelsPerMeter, unused
            0,
            0,
            0,
            0,
            // DWORD biClrUsed, the number of color indexes of palette, unused
            0,
            0,
            0,
            0,
            // DWORD biClrImportant, unused
            0,
            0,
            0,
            0,
        ];

        const iPadding = (4 - ((biWidth * 3) % 4)) % 4;

        const aImgData = oData.data;

        let strPixelData = "";
        const biWidth4 = biWidth << 2;
        let y = biHeight;
        const fromCharCode = String.fromCharCode;

        do {
            const iOffsetY = biWidth4 * (y - 1);
            let strPixelRow = "";
            for (let x = 0; x < biWidth; x++) {
                const iOffsetX = x << 2;
                strPixelRow +=
                    fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
                    fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
                    fromCharCode(aImgData[iOffsetY + iOffsetX]);
            }

            for (let c = 0; c < iPadding; c++) {
                strPixelRow += String.fromCharCode(0);
            }

            strPixelData += strPixelRow;
        } while (--y);

        return (
            encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) +
            encodeData(strPixelData)
        );
    };

    /**
     * saveAsImage
     * @param canvas canvasElement
     * @param width {String} image type
     * @param height {Number} [optional] png width
     * @param type {string} [optional] png height
     * @param fileName {String} image name
     */
    const saveAsImage = function (canvas, width, height, type, fileName) {
        // save file type
        const fileType = type;
        if ($support.canvas && $support.dataURL) {
            if (typeof canvas == "string") {
                canvas = document.getElementById(canvas);
            }
            if (type === undefined) {
                type = "png";
            }
            type = fixType(type);
            if (/bmp/.test(type)) {
                const data = getImageData(scaleCanvas(canvas, width, height));
                const strData = genBitmapImage(data);
                // use new parameter: fileType
                saveFile(makeURI(strData, downloadMime), fileType, fileName);
            } else {
                const strData = getDataURL(canvas, type, width, height);
                // use new parameter: fileType
                saveFile(strData.replace(type, downloadMime), fileType, fileName);
            }
        }
    };

    const convertToImage = function (canvas, width, height, type) {
        if ($support.canvas && $support.dataURL) {
            if (typeof canvas == "string") {
                canvas = document.getElementById(canvas);
            }
            if (type === undefined) {
                type = "png";
            }
            type = fixType(type);

            if (/bmp/.test(type)) {
                const data = getImageData(scaleCanvas(canvas, width, height));
                const strData = genBitmapImage(data);
                return genImage(makeURI(strData, "image/bmp"));
            } else {
                const strData = getDataURL(canvas, type, width, height);
                return genImage(strData);
            }
        }
    };

    return {
        saveAsImage: saveAsImage,
        saveAsPNG: function (canvas, width, height, fileName) {
            return saveAsImage(canvas, width, height, "png", fileName);
        },
        saveAsJPEG: function (canvas, width, height, fileName) {
            return saveAsImage(canvas, width, height, "jpeg", fileName);
        },
        saveAsGIF: function (canvas, width, height, fileName) {
            return saveAsImage(canvas, width, height, "gif", fileName);
        },
        saveAsBMP: function (canvas, width, height, fileName) {
            return saveAsImage(canvas, width, height, "bmp", fileName);
        },

        convertToImage: convertToImage,
        convertToPNG: function (canvas, width, height) {
            return convertToImage(canvas, width, height, "png");
        },
        convertToJPEG: function (canvas, width, height) {
            return convertToImage(canvas, width, height, "jpeg");
        },
        convertToGIF: function (canvas, width, height) {
            return convertToImage(canvas, width, height, "gif");
        },
        convertToBMP: function (canvas, width, height) {
            return convertToImage(canvas, width, height, "bmp");
        },
    };
})();

 
//export default Canvas2Image;

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值