【问题标题】:Image is downloaded as .png after cropping the image裁剪图像后,图像下载为 .png
【发布时间】:2020-10-18 04:52:06
【问题描述】:

我已经修改了来自 repo 的代码来裁剪图像。 目标是上传文件。采用可接受的格式。裁剪文件,然后将其下载或上传到 cloudinary。

当我上传 svg 并裁剪文件时,下载的文件是“.png”。请帮助我进行调试。


handleDownloadClick = (event) => {
        event.preventDefault();
        const { imgSrc } = this.state;

        //To handle the name of the file while downloading

        var fileName = `${this.fileInputRef.current.files[0].name}`;
        var remove_after = fileName.indexOf(".");
        var finalFileName = fileName.substring(0, remove_after);

        if (imgSrc) {
            const canvasRef = this.imagePreviewCanvasRef.current;

            const { imgSrcExt } = this.state;
            console.log(imgSrcExt);
            const imageData64 = canvasRef.toDataURL("image/" + imgSrcExt);

            const myFilename = `${finalFileName}`;

            // file to be uploaded
            const myNewCroppedFile = base64StringtoFile(
                imageData64,
                myFilename
            );
            console.log(myNewCroppedFile);
            // download file
            downloadBase64File(imageData64, myFilename);
            this.handleClearToDefault();
        }
    };

【问题讨论】:

  • image/svg 不是画布可以导出的类型 - 因为 SVG 实际上不是图像,但画布是(SVG 不直接保存任何像素数据,除非作为其他东西嵌入)。如果您尝试将 image/svg 作为输出,canvas 将忽略它并仅使用 image/png 作为默认值,因为该值无效。
  • 您好,感谢您提供的信息。有没有办法将图像下载为 svg
  • 从文件中加载 SVG 节点,修改节点本身以进行裁剪,然后将更改后的 SVG 节点作为文本上传。 SVG data !== pixels 根本没有,所以通过画布会破坏你的 svg 数据。您需要修改 SVG 根目录上的 viewBox 属性以“裁剪”一个 svg,但我预见到很多例外情况会使它变得复杂。为什么还需要裁剪 SVG?通常它只是不被接受的裁剪文件格式。

标签: reactjs svg canvas


【解决方案1】:

要裁剪 SVG,您需要更改 viewBox 属性以及 SVG widthheight 属性。

示例裁剪和填充 SVG 徽标

var size = 300;
   const baseSize = 300, resizeBy = 20, minSize = 30;
crop.addEventListener("click", () => resizeSvg(-resizeBy));
pad.addEventListener("click", () => resizeSvg(resizeBy));

function resizeSvg(amount) {
    size = size + amount < minSize ? minSize : size + amount;
    const edge = (baseSize - size) / 2
    svgLogo.setAttribute("width", size);
    svgLogo.setAttribute("height", size);
    svgLogo.setAttribute("viewBox", [edge, edge, size, size].join(" "));

}
svg {border: 2px solid}
<button id="crop">Crop 20px</button>
<button id="pad">Pad 20px</button><br>

<svg id="svgLogo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="300" viewBox="0 0 300 300">

  <title>SVG Logo</title> <defs> <g id="SVG" fill="#ffffff" transform="scale(2) translate(20,79)"> <path id="S" d="M 5.482,31.319 C2.163,28.001 0.109,23.419 0.109,18.358 C0.109,8.232 8.322,0.024 18.443,0.024 C28.569,0.024 36.782,8.232 36.782,18.358 L26.042,18.358 C26.042,14.164 22.638,10.765 18.443,10.765 C14.249,10.765 10.850,14.164 10.850,18.358 C10.850,20.453 11.701,22.351 13.070,23.721 L13.075,23.721 C14.450,25.101 15.595,25.500 18.443,25.952 L18.443,25.952 C23.509,26.479 28.091,28.006 31.409,31.324 L31.409,31.324 C34.728,34.643 36.782,39.225 36.782,44.286 C36.782,54.412 28.569,62.625 18.443,62.625 C8.322,62.625 0.109,54.412 0.109,44.286 L10.850,44.286 C10.850,48.480 14.249,51.884 18.443,51.884 C22.638,51.884 26.042,48.480 26.042,44.286 C26.042,42.191 25.191,40.298 23.821,38.923 L23.816,38.923 C22.441,37.548 20.468,37.074 18.443,36.697 L18.443,36.692 C13.533,35.939 8.800,34.638 5.482,31.319 L5.482,31.319 L5.482,31.319 Z"/><path id="V" d="M 73.452,0.024 L60.482,62.625 L49.742,62.625 L36.782,0.024 L47.522,0.024 L55.122,36.687 L62.712,0.024 L73.452,0.024 Z"/> <path id="G" d="M 91.792,25.952 L110.126,25.952 L110.126,44.286 L110.131,44.286 C110.131,54.413 101.918,62.626 91.792,62.626 C81.665,62.626 73.458,54.413 73.458,44.286 L73.458,44.286 L73.458,18.359 L73.453,18.359 C73.453,8.233 81.665,0.025 91.792,0.025 C101.913,0.025 110.126,8.233 110.126,18.359 L99.385,18.359 C99.385,14.169 95.981,10.765 91.792,10.765 C87.597,10.765 84.198,14.169 84.198,18.359 L84.198,44.286 L84.198,44.286 C84.198,48.481 87.597,51.880 91.792,51.880 C95.981,51.880 99.380,48.481 99.385,44.291 L99.385,44.286 L99.385,36.698 L91.792,36.698 L91.792,25.952 L91.792,25.952 Z"/> </g> </defs>
 <path id="base" fill="#000" d="M8.5,150 H291.5 V250 C291.5,273.5 273.5,291.5 250,291.5 H50 C26.5,291.5 8.5,273.5 8.5,250 Z"/>
   <g stroke-width="38.0086" stroke="#000">
     <g id="svgstar" transform="translate(150, 150)">
       <path id="svgbar" fill="#ffb13b" 
         d="M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z"/>
       <use xlink:href="#svgbar" transform="rotate(45)"/><use xlink:href="#svgbar" transform="rotate(90)"/><use xlink:href="#svgbar" transform="rotate(135)"/> </g></g> <use xlink:href="#svgstar"/><use xlink:href="#base" opacity="0.85"/><use xlink:href="#SVG"/>

</svg>

【讨论】:

    【解决方案2】:

    Canvas 用于处理基于像素的数据,因此它可以输入 SVG 并将其渲染为画布上的图像,但您实际上无法取出 SVG,因为 SVG 不是 像素 em>,它们是对象的描述。因此,为了再次将图像存储为 SVG,您必须将像素数据嵌入到 SVG 元素中——但此时,它没有任何区别。无法使用画布裁剪 SVG,因为画布会渲染像素并丢失 SVG 数据。

    这也解释了为什么向画布询问 image/svg 输出不起作用 - 它只会退回到输出画布可以描述,基于像素的格式,如 jpeg 或 @987654323 @。这样你就得到了一个.png 文件。

    裁剪 SVG 需要更改 svg 标签上的属性,例如 viewBoxwidthheight,它们需要与使用画布完全不同的过程。

    SVG 裁剪示例

    为了裁剪 SVG 图像,您不需要调整它们的宽度和高度属性,只需调整 viewBox(宽度和高度在这里并不重要)。这是一个例子:

    const svg = document.getElementById( 'svg' );
    
    document.getElementById( 'crop' ).addEventListener( 'input', event => {
      
      const size = event.target.value;
      const coordinate = ((1 - size) / 2);
      
      svg.setAttribute( 'viewBox', `${coordinate} ${coordinate} ${size} ${size}` );
       
    })
    <svg id="svg" width="100px" height="100px" viewBox="0 0 1 1" xmlns="http://www.w3.org/2000/svg">
      <circle cx=".5" cy=".5" r=".5" fill="red" />
      <circle cx=".5" cy=".5" r=".4" fill="blue" />
      <circle cx=".5" cy=".5" r=".3" fill="green" />
      <circle cx=".5" cy=".5" r=".2" fill="yellow" />
      <circle cx=".5" cy=".5" r=".1" fill="pink" />
    </svg>
    
    <br />
    <p>Change cropping on SVG using viewBox</p>
    <input type="range" id="crop" min=".1" max="1" step=".01" />

    【讨论】:

    • 当然。我的方法是一样的。只是对于其他文件格式,我还需要通过裁剪器运行一次。
    • 然后检测并为 SVG 使用不同的裁剪功能 - 因为您在此过程中丢失了 SVG 数据。那有什么意义呢?保存 SVG 通常更好,因为在大多数情况下它比图像占用更少的空间。无论如何,我添加了一种“裁剪”SVG 文件的方法。
    猜你喜欢
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 2017-05-22
    • 2021-07-26
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多