You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何添加按钮导出指定div为1080×1920比例的PNG图片?

问题描述

我用ChatGPT做了一个基础网站,想加个按钮保存网站里显示的9:16(1080x1920)比例图片。上传图片后预览效果如图1,目标导出效果如图2,原始图片如图3。我知道可以截图,但想简化操作并保证宽高比。

按照建议用html2canvas修改代码后遇到两个问题:

  • 导出的是整个网站,而非id为image-container的div
  • 预览里的模糊背景层没被导出,只保留了阴影

初始代码

<!DOCTYPE html>
<html>
  <head>
    <title>IMG to IG</title>
    <style>
        /* Style for the image container */
        .image-container {
          right: 8px;
          width: 1080px; /* Set width to HD+ */
          height: 1920px; /* Set height to HD+ */
          display: flex;
          justify-content: center; /* Center the images horizontally */
          align-items: center;
          height: 100vh;  /*Set the container height to the full viewport height */
          position: relative; /* Set position to relative for absolute positioning of images */
          pointer-events: none;
        }
        
        /* Style for the blurred image - Image in Background */
        .image-container .blurred-image { 
          width: 1080px; /* Set width to HD+ */
          height: 1920px; /* Set height to HD+ */
          object-fit: cover; /* Scale image to desired aspect ratio by occupies all the available space */
          filter: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='a' x='0' y='0' width='1' height='1' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='4' result='b'/%3E%3CfeMorphology operator='dilate' radius='4'/%3E %3CfeMerge%3E%3CfeMergeNode/%3E%3CfeMergeNode in='b'/%3E%3C/feMerge%3E%3C/filter%3E %3C/svg%3E#a");
          pointer-events: none;
        }

        /* Style for the original image - Image in center */
        .image-container .original-image {
          width: 80%;
          position: absolute; /* Position the image absolutely */
          top: 50%; /* Position from the top */
          left: 50%; /* Position from the left */
          transform: translate(-50%, -50%); /* Center the image */
          filter: drop-shadow(15px 15px 8px rgba(0, 0, 0, 0.6)) ;
          pointer-events: none;
        }

      </style>

  <body>
  <input id="upload" type="file" accept="image/*" onchange="loadImage(event)">
  <div class="image-container">
    <img id="blurredImage" class="blurred-image blur-effect" >
    <img id="originalImage" class="original-image">
  </div>
   
  <script>
    // Function to load the selected image
    function loadImage(event) {
      var originalImage = document.getElementById("originalImage");
      var blurredImage = document.getElementById("blurredImage");
      var reader = new FileReader();
      reader.onload = function(){
        originalImage.src = reader.result;
        blurredImage.src = reader.result;
      }
      reader.readAsDataURL(event.target.files[0]);
    }
  </script>
</body>
</html>

修改后的代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <!-- Title -->
    <title>IMG to IG</title>
    <!-- Download and Include -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    <style>
        /* Style for the image container */
        .image-container {
          right: 8px;
          width: 1080px; /* Set width to HD+ */
          height: 1920px; /* Set height to HD+ */
          display: flex;
          justify-content: center; /* Center the images horizontally */
          align-items: center;
          height: 100vh;  /*Set the container height to the full viewport height */
          position: relative; /* Set position to relative for absolute positioning of images */
          pointer-events: none;
        }
        
        /* Style for the blurred image - Image in Background */
        .image-container .blurred-image { 
          width: 1080px; /* Set width to HD+ */
          height: 1920px; /* Set height to HD+ */
          object-fit: cover; /* Scale image to desired aspect ratio by occupies all the available space */
          filter: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='a' x='0' y='0' width='1' height='1' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='4' result='b'/%3E%3CfeMorphology operator='dilate' radius='4'/%3E %3CfeMerge%3E%3CfeMergeNode/%3E%3CfeMergeNode in='b'/%3E%3C/feMerge%3E%3C/filter%3E %3C/svg%3E#a");
          pointer-events: none;
        }

        /* Style for the original image - Image in center */
        .image-container .original-image {
          width: 80%;
          position: absolute; /* Position the image absolutely */
          top: 50%; /* Position from the top */
          left: 50%; /* Position from the left */
          transform: translate(-50%, -50%); /* Center the image */
          filter: drop-shadow(15px 15px 8px rgba(0, 0, 0, 0.6)) ;
          pointer-events: none;
        }

      </style>
  </head>
  <body>
  <input id="upload" type="file" accept="image/*" onchange="loadImage(event)">

  <div class="image-container" id='image-container'>
    <img id="blurredImage" class="blurred-image blur-effect" >
    <img id="originalImage" class="original-image">
  </div>

  <div id="download">
    <a id="download-link" download="screenshot.png">Download Screenshot</a>
  </div>

  <input type='button' id='but_screenshot' value='Take screenshot' onclick='screenshot();'><br/>

  <script>
    // Function to load the selected image
    function loadImage(event) {
      var originalImage = document.getElementById("originalImage");
      var blurredImage = document.getElementById("blurredImage");
      var reader = new FileReader();
      reader.onload = function(){
        originalImage.src = reader.result;
        blurredImage.src = reader.result;
      }
      reader.readAsDataURL(event.target.files[0]);
    }
  
  // Script for screenshot
    function screenshot(){
      html2canvas(document.getElementById("image-container")).then(canvas => {
        document.body.appendChild(canvas);
        var downloadLink = document.querySelector('#download-link');
        downloadLink.href = canvas.toDataURL("image/png");
        downloadLink.style.display = 'inline';
      });
    }
  </script>
</body>
</html>
解决方案

问题1:导出整个网站而非目标div

你的.image-container样式里同时设置了height: 1920px和height: 100vh,后者会覆盖前者,导致容器高度变成视口高度。当html2canvas渲染时,会按照这个实际高度生成画布,加上页面其他元素(上传按钮、截图按钮),最终导出整个页面。

修复方法:删除height: 100vh,确保容器高度固定为1920px:

.image-container {
  right: 8px;
  width: 1080px;
  height: 1920px; /* 保留固定高度,删除height:100vh */
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  pointer-events: none;
}

问题2:模糊背景层未被导出

html2canvas对复杂的SVG滤镜支持有限,你使用的url()引用内嵌SVG滤镜无法被正确渲染。可以改用CSS原生的blur()滤镜替代:

替换模糊滤镜样式:

.image-container .blurred-image { 
  width: 1080px;
  height: 1920px;
  object-fit: cover;
  /* 替换原有filter为以下代码 */
  filter: blur(4px) saturate(1.1);
  pointer-events: none;
}

如果需要和原滤镜效果更接近,可以调整blur()的数值,比如blur(8px),再配合其他滤镜组合。

优化后的完整代码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>IMG to IG</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    <style>
        .image-container {
          right: 8px;
          width: 1080px;
          height: 1920px;
          display: flex;
          justify-content: center;
          align-items: center;
          position: relative;
          pointer-events: none;
        }
        
        .image-container .blurred-image { 
          width: 1080px;
          height: 1920px;
          object-fit: cover;
          filter: blur(4px) saturate(1.1);
          pointer-events: none;
        }

        .image-container .original-image {
          width: 80%;
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          filter: drop-shadow(15px 15px 8px rgba(0, 0, 0, 0.6));
          pointer-events: none;
        }

        /* 避免按钮和容器重叠 */
        #upload, #but_screenshot, #download-link {
          margin: 10px;
          padding: 8px 12px;
          display: inline-block;
        }
      </style>
  </head>
  <body>
  <input id="upload" type="file" accept="image/*" onchange="loadImage(event)">
  <input type='button' id='but_screenshot' value='生成并下载图片' onclick='screenshot();'><br/>
  <div id="download">
    <a id="download-link" download="ig-image.png" style="display:none;">点击下载</a>
  </div>

  <div class="image-container" id='image-container'>
    <img id="blurredImage" class="blurred-image" >
    <img id="originalImage" class="original-image">
  </div>

  <script>
    function loadImage(event) {
      const originalImage = document.getElementById("originalImage");
      const blurredImage = document.getElementById("blurredImage");
      const reader = new FileReader();
      reader.onload = function(){
        originalImage.src = reader.result;
        blurredImage.src = reader.result;
      }
      reader.readAsDataURL(event.target.files[0]);
    }
  
    function screenshot(){
      html2canvas(document.getElementById("image-container"), {
        scale: 1, // 保持原分辨率
        useCORS: true // 处理跨域图片
      }).then(canvas => {
        const downloadLink = document.querySelector('#download-link');
        downloadLink.href = canvas.toDataURL("image/png");
        downloadLink.style.display = 'inline';
        downloadLink.click(); // 自动触发下载
      });
    }
  </script>
</body>
</html>

额外说明

  • 自动触发下载:添加downloadLink.click(),生成图片后直接下载,无需用户二次点击
  • 分辨率保持:设置scale:1确保导出图片为1080x1920原尺寸
  • 按钮样式:添加基础样式避免按钮与图片容器重叠

内容的提问来源于stack exchange,提问作者Kavista_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:09:19