Skip to content
Snippets Groups Projects
drawImage.ts 13.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • import G = require("./globals");
    import * as $ from "jquery";
    import Help = require("./helper");
    import { DrawChart } from "./drawChart";
    export class DrawImage {
      public _drawChart: DrawChart;
    
      private _image = G.Image.getInstance();
      private readonly _saturationSliderID: string = "SaturationSlider";
      private readonly _replotButtonID: string = "rePlot";
      private readonly _transparencySliderID: string = "TrasparencySlider";
      private readonly _resetID: string = "reset";
      private readonly _exportImageID: string = "ExportImage";
      private readonly _selectionCanvasID: string;
    
    Fabio Proietti's avatar
    Fabio Proietti committed
      private readonly _myCanvasID: string = "myCanvas";
    
    
      private _context: CanvasRenderingContext2D;
    
      private _saturationSlider: HTMLInputElement;
      private _replotButton: HTMLButtonElement;
      private _transparencySlider: HTMLInputElement;
      private _reset: HTMLDivElement;
      private _exportImage: HTMLDivElement;
      private _pixel1: G.coordinates;
      private _pixel2: G.coordinates;
      private _xMinRange: number;
      private _xMaxRange: number;
    
      private _selectionCanvas: HTMLCanvasElement;
    
    Fabio Proietti's avatar
    Fabio Proietti committed
      private _myCanvas: HTMLCanvasElement;
    
      private _ctx;
    
      private _startX: number;
      private _startY: number;
      private _mouseX: number;
      private _mouseY: number;
      private _isDown = false;
    
      constructor(canvas: string) {
        this._drawChart = new DrawChart(this);
    
        this._selectionCanvasID = canvas;
        this._selectionCanvas = <HTMLCanvasElement>document.getElementById(this._selectionCanvasID);
        this._ctx = this._selectionCanvas.getContext("2d");
    
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        this._myCanvas = <HTMLCanvasElement>document.getElementById(this._myCanvasID); 
    
    
        this._saturationSlider = <HTMLInputElement>document.getElementById(this._saturationSliderID);
        this._replotButton = <HTMLButtonElement>document.getElementById(this._replotButtonID);
        this._transparencySlider = <HTMLInputElement>document.getElementById(this._transparencySliderID);
        this._reset = <HTMLDivElement>document.getElementById(this._resetID);
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        this._exportImage = <HTMLDivElement>document.getElementById(this._exportImageID);
        
        this._saturationSlider.addEventListener("mouseup", this.saturationSliderMouseUp, false);
        this._replotButton.addEventListener("click", this.replotButtonClick, false);
        this._transparencySlider.addEventListener("mouseup", this.trasparencySliderMouseUp, false);
        this._reset.addEventListener("click", this.resetClick, false);
        this._exportImage.addEventListener("click", this.exportImageClick, false);
    
        this._selectionCanvas.addEventListener("mousedown", this.selectionCanvasMouseDown, false);
        this._selectionCanvas.addEventListener("mouseup", this.clickdown, false);
        this._selectionCanvas.addEventListener("mousemove", this.selectionCanvasMouseMove, false);
        this._selectionCanvas.addEventListener("mouseup", this.selectionCanvasMouseUp, false);
        this._selectionCanvas.addEventListener("mouseout", this.selectionCanvasMouseOut, false);
    
    
      }
    
      private saturationSliderMouseUp = (event: MouseEvent): void => {
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
    
      };
      private replotButtonClick = (event: MouseEvent) => {
        //bottone per colorare con il max relativo
        this._image.rePrint = true;
        this._saturationSlider.value = "100";
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        // opacity value?
        this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
    
      };
    
      private trasparencySliderMouseUp = (event: MouseEvent) => {
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        this.drawImg(this._image, this._pixel1, this._pixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
    
      };
    
      private resetClick = (event: MouseEvent) => {
        this._image.newOrigin = { x: 0, y: 0 };
        this._image.rePrint = false;
        G.Chart.getInstance().calibrated = false;
        this._image.globalxMinRange = 0;
        this._image.globalxMaxRange = this._image.channelDepth;
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        this._saturationSlider.value = "100";
        this._transparencySlider.value = "0";
    
        this._drawChart.spinBoxMin.setAttribute("value", "-");
        this._drawChart.spinBoxMax.setAttribute("value", "-");
    
        this.drawImg(this._image, { x: 0, y: 0 }, { x: this._image.width - 1, y: this._image.height - 1 }, 0, this._image.channelDepth);
        this._drawChart.drawChart(this._image, { x: 0, y: 0 }, { x: this._image.width - 1, y: this._image.height - 1 }, 0, this._image.channelDepth);
      };
    
      private exportImageClick = (event: MouseEvent) => {
        //esportazione immagine
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        let img = this._selectionCanvas.toDataURL("image/png"); 
        this._selectionCanvas.setAttribute("href", img.replace("image/png", "image/octet-stream"));
        document.getElementById("ExportLink").setAttribute("href", img);
    
      };
      private clickdown = (event: MouseEvent): void => {
        this.setPosition(event, this._image.zPixel2, this._selectionCanvasID);
        let tmp: number;
    
        if (this._image.zPixel1.y > this._image.zPixel2.y) {
          tmp = this._image.zPixel1.y;
          this._image.zPixel1.y = this._image.zPixel2.y;
          this._image.zPixel2.y = tmp;
        }
        //se è stato cliccato un punto disegno il grafico, altrimenti disegno anche il
        //canvas e aggiorno l'origine
        if (this._image.zPixel1.x != this._image.zPixel2.x || this._image.zPixel1.y != this._image.zPixel2.y) {
    
          this._image.newOrigin = { x: this._image.zPixel1.x, y: this._image.zPixel1.y };
          this.drawImg(this._image, this._image.zPixel1, this._image.zPixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
        }
    
        this._drawChart.drawChart(this._image, this._image.zPixel1, this._image.zPixel2, this._image.globalxMinRange, this._image.globalxMaxRange);
      };
      private selectionCanvasMouseDown = (event: MouseEvent) => {
        event.preventDefault();
        event.stopPropagation();
    
        //calculate mouse position
        let scrollTOP: number = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
        let scrollLEFT: number = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft;
        let allX: number = event.clientX + scrollLEFT;
        let allY: number = event.clientY + scrollTOP;
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        let elParent: any = this._myCanvas;
    
        let objX: number = 0, objY: number = 0;
        while (elParent) {
          objX += elParent.offsetLeft;
          objY += elParent.offsetTop;
          elParent = elParent.offsetParent;
        }
        this._startX = allX - objX;
        this._startY = allY - objY;
    
        // set a flag indicating the drag has begun
        this._isDown = true;
      };
    
      private selectionCanvasMouseUp = (event: MouseEvent) => {
        event.preventDefault();
        event.stopPropagation();
    
        // the drag is over, clear the dragging flag
        this._isDown = false;
        //this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height);
      };
      private selectionCanvasMouseMove = (event: MouseEvent) => {
        event.preventDefault();
        event.stopPropagation();
    
        // if we're not dragging, just return
        if (!this._isDown) {
          return;
        }
    
        //calculate mouse position
        let scrollTOP: number = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
        let scrollLEFT: number = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft;
    
        let allX: number = event.clientX + scrollLEFT;
        let allY: number = event.clientY + scrollTOP;
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        let elParent: any = this._myCanvas;
    
        let objX: number = 0, objY: number = 0;
        while (elParent) {
          objX += elParent.offsetLeft;
          objY += elParent.offsetTop;
          elParent = elParent.offsetParent;
        }
        this._mouseX = allX - objX;
        this._mouseY = allY - objY;
    
        // clear the canvas
        //this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height);
    
        // calculate the rectangle width/height based
        // on starting vs current mouse position
        let width = this._mouseX - this._startX;
        let height = this._mouseY - this._startY;
    
        // draw a new rect from the start position
        // to the current mouse position
        this._ctx.fillRect(this._startX, this._startY, width, height);
      };
      private selectionCanvasMouseOut = (event: MouseEvent) => {
    
        event.preventDefault();
        event.stopPropagation();
    
        // the drag is over, clear the dragging flag
        this._isDown = false;
        //this._ctx.clearRect(0, 0, this._selectionCanvas.width, this._selectionCanvas.height);
      };
    
      //Il metodo findPosition definisce la posizione del cursore del mouse
      //relativa al canvas nel momento in cui avviene l'evento passato in input
      private setPosition(event: any, pixel: G.coordinates, canvasID: string) {
        let image = G.Image.getInstance();
        let scrollTOP: number = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
        let scrollLEFT: number = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft;
        let allX: number = event.clientX + scrollLEFT;
        let allY: number = event.clientY + scrollTOP;
        let elParent: any = document.getElementById(canvasID);
        let objX: number = 0,
          objY: number = 0;
        while (elParent) {
          objX += elParent.offsetLeft;
          objY += elParent.offsetTop;
          elParent = elParent.offsetParent;
        }
    
        pixel.x = Math.floor((allX - objX - 1) / image.pixelDim) + image.newOrigin.x;
        pixel.y = Math.floor((allY - objY - 1) / image.pixelDim) + image.newOrigin.y;
      }
      drawImg(image: G.Image, pixel1: G.coordinates, pixel2: G.coordinates, xMinRange: number, xMaxRange: number, callback?: () => void) {
        this._pixel1 = pixel1;
        this._pixel2 = pixel2;
        //alert("disegno in corso");
    
        //numero di pixel per dimensione
        let nPixelX: number = this._pixel2.x - this._pixel1.x + 1;
        let nPixelY: number = this._pixel2.y - this._pixel1.y + 1;
    
        //dimensione dei canvas
        let mappaPannelDim: any = document.querySelector("#mappa-pannel").getBoundingClientRect();
        let mappaWidth: number = mappaPannelDim.right - mappaPannelDim.left - 40;
        let mappaHeigth: number = 400;
    
        //dimensione reale dei pixel
        let dimPixelx: number = Math.floor(mappaWidth / nPixelX);
        let dimPixely: number = Math.floor(mappaHeigth / nPixelY);
        image.pixelDim = dimPixelx < dimPixely ? dimPixelx : dimPixely;
    
        //dimensioni esatte dei canvas
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        this._myCanvas.height = nPixelY * image.pixelDim;
        this._myCanvas.width = nPixelX * image.pixelDim;
        this._selectionCanvas.height = nPixelY * image.pixelDim;
        this._selectionCanvas.width = nPixelX * image.pixelDim;
        let ctx = this._myCanvas.getContext("2d"); //contesto del canvas
    
    
        if (xMaxRange - xMinRange >= image.channelDepth) {
          //range completo
          let max: number = 0; //massimo relativo o assoluto
          if (image.rePrint) {
            max = Help.findMax(image.nOfCounts, this._pixel1, this._pixel2);
          } else {
            max = image.maxAbsolute;
          }
    
    Fabio Proietti's avatar
    Fabio Proietti committed
          
          max *= parseInt(this._saturationSlider.value) / 100;
    
          this.drawCanvas(image, image.nOfCounts, max);
    
        } else {
          //range parziale (solo alcuni canali)
          let xMinRangeCh: number = Math.floor((xMinRange * 1000 + this._image.calibration.b) / this._image.calibration.a - 1); //16
          let xMaxRangeCh: number = Math.floor((xMaxRange * 1000 + this._image.calibration.b) / this._image.calibration.a - 1); //16371
          //calcolo il numero di conteggi solo dei canali selezionati
          let nOfCountsRelative: number[][];
          nOfCountsRelative = new Array(image.width);
          for (let i: number = 0; i < image.width; i++) {
            nOfCountsRelative[i] = new Array(image.height);
            for (let j: number = 0; j < image.height; j++) {
              nOfCountsRelative[i][j] = Help.sumVect(image.DataMatrix[i][j], xMinRangeCh, xMaxRangeCh);
            }
          }
          //calcolo il massimo
    
    Fabio Proietti's avatar
    Fabio Proietti committed
          let max: number = 0;
    
          if (image.rePrint) {
            max = Help.findMax(nOfCountsRelative, this._pixel1, this._pixel2);
          } else {
            max = Help.findMax(nOfCountsRelative, { x: 0, y: 0 }, { x: image.width - 1, y: image.height - 1 });
          }
    
    Fabio Proietti's avatar
    Fabio Proietti committed
          max *= parseInt(this._saturationSlider.value) / 100;
          
    
          if(max == 0)
            alert("WARNING: max value is 0");
          else
            this.drawCanvas(image, nOfCountsRelative, max);
    
        }
    
        if (typeof (callback) != typeof (undefined))
          callback();
      }
      private drawCanvas(image: G.Image, noc, max) {
        //controllo il valore della trasparenza
    
    Fabio Proietti's avatar
    Fabio Proietti committed
        
        let setTrsp: number = 1 - parseInt(this._transparencySlider.value) / 100;
    
    
        //scorro tutti i pixel: ne determino il colore e li disegno
        let color: string = "";
        for (let i: number = this._pixel1.x; i <= this._pixel2.x; i++) {
          for (let j: number = this._pixel1.y; j <= this._pixel2.y; j++) {
            let intensity: number = noc[i][j] / max;
            if (intensity < 1 / 5)
              //blu
              color = "rgba(0, 0, " + Math.floor(intensity * 5 * 255) + "," + setTrsp + ")";
            else if (1 / 5 <= intensity && intensity < 2 / 5)
              //blu+verde
              color = "rgba(0, " + Math.floor((intensity - 1 / 5) * 5 * 255) + ",255, " + setTrsp + ")";
            else if (2 / 5 <= intensity && intensity < 3 / 5)
              // verde-blu
              color = "rgba(0, 255, " + (255 - Math.floor((intensity - 2 / 5) * 5 * 255)) + ", " + setTrsp + ")";
            else if (3 / 5 <= intensity && intensity < 4 / 5)
              //verde + rosso
              color = "rgba(" + Math.floor((intensity - 3 / 5) * 5 * 255) + ",255,0," + setTrsp + ")";
            //rosso -verde
            else
              color = "rgba(255," + (255 - Math.floor((intensity - 4 / 5) * 5 * 255)) + ", 0, " + setTrsp + ")";
    
            this._ctx.fillStyle = color;
            this._ctx.fillRect((i - this._pixel1.x) * image.pixelDim, (j - this._pixel1.y) * image.pixelDim, image.pixelDim, image.pixelDim);
          }
        }
        //console.log(color);
        image.rePrint = false; //annullo rePrint
        this._ctx.fillStyle = "rgba(0, 110, 255, 0.25)";
    
        this._isDown = false;