1

Canvas生成缩略图

 1 year ago
source link: https://www.clzczh.top/2022/06/18/Canvas%E7%94%9F%E6%88%90%E7%BC%A9%E7%95%A5%E5%9B%BE/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Canvas生成缩略图

个人博客的图片太大了,想换成缩略图,正好学了点Canvas,发现用Canvas画出来的图片就有点缩略图的感觉,于是就开始搞起来了

利用canvas实现绘制图片

先通过canvas.getContext('2d')获取2D绘图上下文,然后调用绘图上下文的drawImage方法,实现图片的绘制。详情可查看之前写的Canvas的文章。

<canvas id="mycanvas" width="640" height="360"></canvas>
 const mycanvas = document.getElementById('mycanvas')

const context = mycanvas.getContext("2d");

// 获取图像
const img = new Image();
img.src = "./big.png";

// 图片加载完成后,绘制图片到canvas上
img.onload = () => {
    context.drawImage(img, 0, 0, 640, 360);
}
image-20220521184441072
image-20220521184441072

上面我们就已经绘制图片了,但是下载图片比较麻烦,得通过右键浏览器自带的另存方法。

所以我们可以通过Canvas的toDataURL方法,将绘制的图片转成base64编码,然后通过a链接方式下载。具体的下载方法的实现同样可以查看以前写的文章。(偷懒,不想贴地址,手动狗头)

const mycanvas = document.getElementById('mycanvas')

const context = mycanvas.getContext("2d");

// 获取图像
const img = new Image();
img.src = "./big.png";

// 图片加载完成后,绘制图片到canvas上
img.onload = () => {
    context.drawImage(img, 0, 0, 640, 360);


    const a = document.createElement('a')
    a.href = mycanvas.toDataURL()

    // 获取源图片的名字
    a.download = img.src.split('/')[img.src.split('/').length - 1]

    a.click()
}
image-20220521185207447
image-20220521185207447

刷新页面,我们就能发现自动下载了。接下来,我们就来看看,是不是我们想要的效果。

image-20220521185605337
image-20220521185605337

去掉html结构中的canvas

实际上,我们可以自己生成Canvas,然后设置宽高,这样就不需要上DOM树,也能实现下载图片。

const w = 640
const h = 360

const mycanvas = document.createElement('canvas')
mycanvas.width = w
mycanvas.height = h

const context = mycanvas.getContext("2d");

// 获取图像
const img = new Image();
img.src = "./big.png";

// 图片加载完成后,绘制图片到canvas上
img.onload = () => {
    context.drawImage(img, 0, 0, w, h);


    const a = document.createElement('a')
    a.href = mycanvas.toDataURL()

    // 获取源图片的名字
    a.download = img.src.split('/')[img.src.split('/').length - 1]

    a.click()
}

使用input:file实现生成多张缩略图

因为安全的关系,网页中的js访问文件夹下的图片会有很多限制。所以选了一个比较简单地方法,利用input:file来实现。通过input:filefiles属性可以访问选择的文件列表。

下面为了方便,使用了form元素,通过 document.form[0]方式访问form元素,通过form.elements[0]访问input元素。

<form action="#">
    <input type="file" multiple>
</form>
<button onclick="generatePreview()">生成缩略图</button>
const w = 640
const h = 360

function generatePreview() {

    const files = document.forms[0].elements[0].files
    console.log(files)
}
image-20220521191518818
image-20220521191518818

这样子就能够获取选中的文件信息了,但是实际上我们只需要文件数量信息和文件名信息即可。

遍历图片列表,下载图片。(图片的src属性需要改成对应文件名,生成的图片也需要更改名字。)

a.download = fileName.replace(/(\w+)/, '$1_preview')

这里我使用的是正则表达式+replace方法去修改名字(简单版本,勿喷)

  • \w:匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_]
  • +:匹配前面一个表达式 1 次或者多次
  • $1:捕获匹配项,前面的正则表达式中,使用括号包住了\w+,所以$1实际上就是这部分

完整代码:(html文件要放到图片文件夹下才有效)

<body>
  <form action="#">
    <input type="file" multiple>
  </form>
  <button onclick="generatePreview()">生成缩略图</button>

  <script>
    const w = 640
    const h = 360

    function generatePreview() {

      const files = document.forms[0].elements[0].files

      for (const file of files) {
        const fileName = file.name
        console.log(file)

        const mycanvas = document.createElement('canvas')
        mycanvas.width = w
        mycanvas.height = h

        const context = mycanvas.getContext("2d");

        // 获取图像
        const img = new Image();
        img.src = `./${fileName}`;

        // 图片加载完成后,绘制图片到canvas上
        img.onload = () => {
          context.drawImage(img, 0, 0, w, h);


          const a = document.createElement('a')
          a.href = mycanvas.toDataURL()

          // 获取源图片的名字
          a.download = fileName.replace(/(\w+)/, '$1_preview')

          a.click()
        }
      }
    }
  </script>

</body>
image-20220521193533209
image-20220521193533209
image-20220521193331550
image-20220521193331550

另外,直接本地打开,执行会报错,因为没有服务器环境,本地的html网页,本地的图片

本地的位置是没有域名的,所以会认为是跨域,会报错,可以使用VSCodeLive Server插件,然后右键,点击Open with Live Server就能够以服务器环境打开。

image-20220521200601567
image-20220521200601567

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK