【问题标题】:Fabric JS Tint Filter when applied resizes image Ember projectFabric JS Tint Filter 应用时调整图像 Ember 项目的大小
【发布时间】:2021-08-29 21:56:33
【问题描述】:

我在 Emberjs 项目中实现了 Fabric,为放置的图像着色会导致图像在较大的标记中减少。 **更新,这可能是 CORS 问题,因为添加用户图像可以着色并保持其尺寸正确。

组件把手

<div id="select-image-dimensions" class="placeholder canvas-size" {{did-insert this.renderWallCanvas}}>
</div>

组件 javascript

import Component from '@glimmer/component';
import ENV from '../config/environment';
import AWS from 'aws-sdk';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { fabric } from 'fabric';
import Picker from 'vanilla-picker';

export default class WallToDecorateComponent extends Component {
  @service('captured-image') capturedImage;
  @tracked canvasToDecorate = null;
  @tracked isDown = false;
  @tracked currentColor = null;

  @action
  renderWallCanvas() {
    var canvasAspect, imgAspectLandscape, imgAspectPortrait, left, top, scaleFactor, rect;
    let elemSize = document.querySelector('#select-image-dimensions');

    if(elemSize) {
      rect = elemSize.getBoundingClientRect();
      var canvas = document.createElement('canvas');
      canvas.id = 'fabric-canvas-to-decorate';
      canvas.width = rect.width;
      canvas.height = rect.height;
      elemSize.appendChild(canvas);
    }
    canvasAspect = rect.width / rect.height;
    imgAspectLandscape = this.capturedImage.wallImage.width / this.capturedImage.wallImage.height;
    imgAspectPortrait =  this.capturedImage.wallImage.height / this.capturedImage.wallImage.width;

    if (this.capturedImage.wallImage.width > this.capturedImage.wallImage.height) {

      if (canvasAspect >= imgAspectLandscape) {
          scaleFactor = rect.width / this.capturedImage.wallImage.width;
          left = 0;
          top = -((this.capturedImage.wallImage.height * scaleFactor) - rect.height) / 2;
      } else {
          scaleFactor = rect.height / this.capturedImage.wallImage.height;
          top = 0;
          left = -((this.capturedImage.wallImage.width * scaleFactor) - rect.width) / 2;
      }
    } else {

      if (canvasAspect >= imgAspectPortrait) {
          scaleFactor = rect.height / this.capturedImage.wallImage.height;
          left = -((this.capturedImage.wallImage.width * scaleFactor) - rect.width) / 2;
          top = -((this.capturedImage.wallImage.height * scaleFactor) - rect.height) / 2;
      } else {
          scaleFactor = rect.width / this.capturedImage.wallImage.width;
          top = 0;
          left = -((this.capturedImage.wallImage.width * scaleFactor) - rect.width) / 2;
      }
    }

    var canvas = new fabric.Canvas('fabric-canvas-to-decorate');
    canvas.setBackgroundImage(this.capturedImage.wallImage.src, canvas.renderAll.bind(canvas), {
        backgroundImageOpacity: 1,
        backgroundImageStretch: false,

        top: top,
        left: left,
        originX: 'left',
        originY: 'top',
        scaleX: scaleFactor,
        scaleY: scaleFactor
    });
    this.canvasToDecorate = canvas;
  }

  @action
  addImageTemplateToCanvas(event) {
    let targetElement = document.getElementById(event.target.id);
    var imgInstance = new fabric.Image(targetElement, {
      left: 100,
      top: 100,
      angle: 0,
      opacity: 1
    });
    this.canvasToDecorate.add(imgInstance);
  }

...    
  @action
  setColor() {
    if (!this.canvasToDecorate.getActiveObject()) {
      return;
    }

    var canvas2dBackend = new fabric.Canvas2dFilterBackend()
    fabric.filterBackend = canvas2dBackend;
    fabric.filterBackend = fabric.initFilterBackend();

    var colorButton = document.querySelector('#select-color');
    var obj = this.canvasToDecorate.getActiveObject();

    var filter = new fabric.Image.filters.BlendColor({
      color: colorButton.style.background,
      mode: 'tint',
      alpha: 0.5
    });

    obj.filters[16] = filter;
    obj.applyFilters();
    this.canvasToDecorate.renderAll();
  }

  @action
  selectColor() {
    var parent = document.querySelector('#select-color');
    var picker = new Picker(parent);

    picker.onDone = function(color) {
      parent.style.background = color.rgbaString;
    };
    this.currentColor = parent.style.background;
  }

当我在 Fabric 画布上选择图像来更改颜色时,当应用“色调”时,图像会针对模型提供的图像调整大小。下面的关键部分。

  setColor() {
    if (!this.canvasToDecorate.getActiveObject()) {
      return;
    }

    var canvas2dBackend = new fabric.Canvas2dFilterBackend()
    fabric.filterBackend = canvas2dBackend;
    fabric.filterBackend = fabric.initFilterBackend();

    var colorButton = document.querySelector('#select-color');
    var obj = this.canvasToDecorate.getActiveObject();

    var filter = new fabric.Image.filters.BlendColor({
      color: colorButton.style.background,
      mode: 'tint',
      alpha: 0.5
    });

    obj.filters[16] = filter;
    obj.applyFilters();
    this.canvasToDecorate.renderAll();

图像的轮廓不会改变大小,但实际图像会改变,但用户提供的图像除外,

  @action
  addUserImageFile(){
    let preview = document.getElementById('imageToUpload');
    let file = document.getElementById('image-file-upload').files[0];
    const reader = new FileReader();

    if (file.size > 5242880 || !file.name.match(/.(jpg|jpeg|png|gif)$/i)) {
        return alert("The file must be an image (jpg|jpeg|png|gif) and less than " + (5242880/1024/1024) + "MB");
    } else {
      reader.addEventListener("load", function () {
        // convert image file to base64 string
        preview.src = reader.result;

      }, false);

      if (file) {
        reader.readAsDataURL(file);
      }
    }
  }

  @action
  async addImageCanvas() {
    let preview = document.getElementById('imageToUpload')
    var imgInstance = new fabric.Image(preview, {
      left: 100,
      top: 100,
      angle: 0,
      opacity: 1
    });
    this.canvasToDecorate.add(imgInstance);
  }

【问题讨论】:

    标签: ember.js fabricjs


    【解决方案1】:

    这是一个图像 CORs 问题,Fabric 确实具有加载图像忽略图像 CORS 的功能,在我的情况下,必须为持有结构画布的服务分配变量 canvas 以便回调找到它。

      @action
      addImageTemplateToCanvas(event) {
    
        var canvas = <what ever your fabric canvas variable is, my case its a service>;
    
        fabric.util.loadImage(event.target.src,
            function (img) {
               var fab_image = new fabric.Image(img);
               canvas.add(fab_image);
               canvas.renderAll();
            },{left:100, top:100, angle: 0, opacity: 1});
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多