Crop image via finger(touch) in Ionic App

2019-04-21 07:26发布

问题:

I am Working on ionic based Application.My ionic app version is 1.2.4. I want to Crop Functionality in my application. I want to crop image Via Touch with irregular Shape. So anyone has Create touch cropper So plz help me.

For more clearly, look at below gif what I want.

Last 2 day I'm googling to find the solution and found that it's easy to do simple crop or square or rectangular crop but not getting crop image by touch.

If anybody has done it then suggest me in the right direction.

回答1:

Pointer event is not working in mobile device, so this is the code with some modification with complete working in Ionic application Or any cross platform application.

 setTimeout(example,0); // ensures that the run us after parsing
   function example(){
   const ctx = canvas.getContext("2d");
   var w = canvas.width;
   var h = canvas.height;
   var cw = w / 2;  // center
   var ch = h / 2;

   var selectLayer = CImageCtx(w,h); // creates a canvas
   var selectedContent = CImageCtx(w,h); // the selected content
   document.getElementById("exampleEle").appendChild(selectedContent);
   var image = new Image;  // the image
   //image.src = "img/temp.png";
   image.src ="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Official_portrait_of_Barack_Obama.jpg/220px-Official_portrait_of_Barack_Obama.jpg";
   // updates the masked result
   function updateSelected(){
     var ctx = selectedContent.ctx;
     ctx.drawImage(image,0,0);
     ctx.globalCompositeOperation = "destination-in";
     ctx.drawImage(selectLayer,0,0);
     ctx.globalCompositeOperation = "source-over";
   }
   function update(){
       // if mouse down then
       if(touch.but){
         // clear the mask if on the right image
         if(touch.oldBut === false && touch.x > 256){
            selectLayer.ctx.clearRect(0,0,w,h);
            touch.but = false;
         }else{
            // draw the red
            selectLayer.ctx.fillStyle = "red";
            fillCircle(touch.x, touch.y, 20, selectLayer.ctx);
         }
         // update the masked result
         updateSelected();
       }
       // clear the canvas
       ctx.clearRect(0,0,w,h);
       // draw the image
       ctx.drawImage(image,0,0);
       // then draw the marking layer over it with comp overlay
       ctx.globalCompositeOperation = "overlay";
       ctx.drawImage(selectLayer,0,0);
       ctx.globalCompositeOperation = "source-over";

       touch.oldBut = touch.but;
       requestAnimationFrame(update);
   }
   requestAnimationFrame(update);
 }
 //#############################################################################
 // helper functions not part of the answer
 //#############################################################################
 const touch  = {
   x : 0, y : 0, but : false,
   events(e){
     console.log("e.type",e);
     const m = touch;
     const bounds = canvas.getBoundingClientRect();
     var rect = e.target.getBoundingClientRect();
     if(e.targetTouches) {
       X   =   parseInt(e.targetTouches[0].pageX - rect.left);
       Y   =   parseInt(e.targetTouches[0].pageY - rect.top);
     }
     m.x = X;
     m.y = Y;
     m.but = e.type === "touchstart" ? true : e.type === "touchend" ? false : m.but;
   }
 };
 (["start","end","move"]).forEach(name => document.addEventListener("touch" + name,touch.events));
 const CImage = (w = 128, h = w) => (c = document.createElement("canvas"),c.width = w,c.height = h, c);
 const CImageCtx = (w = 128, h = w) => (c = CImage(w,h), c.ctx = c.getContext("2d"), c);
 const fillCircle = (l,y=ctx,r=ctx,c=ctx) =>{if(l.p1){c=y; r=leng(l);y=l.p1.y;l=l.p1.x }else if(l.x){c=r;r=y;y=l.y;l=l.x}c.beginPath(); c.arc(l,y,r,0,Math.PI*2); c.fill()}

And For View You have to add this 3 lines of html.

  <div id="exampleEle">

  <canvas id="canvas" width=256 height=256></canvas>
  </div>


回答2:

Basically I'm not ionic developer but After googling I found some code that might be helpful for you.

setTimeout(example,0); // ensures that the run us after parsing
function example(){
  const ctx = canvas.getContext("2d");
  var w = canvas.width;
  var h = canvas.height;
  var cw = w / 2;  // center 
  var ch = h / 2;

  var selectLayer = CImageCtx(w,h); // creates a canvas 
  var selectedContent = CImageCtx(w,h); // the selected content
  document.body.appendChild(selectedContent);
  var image = new Image;  // the image
  image.src ="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Official_portrait_of_Barack_Obama.jpg/220px-Official_portrait_of_Barack_Obama.jpg";
  // updates the masked result
  function updateSelected(){
    var ctx = selectedContent.ctx;
    ctx.drawImage(image,0,0);
    ctx.globalCompositeOperation = "destination-in";
    ctx.drawImage(selectLayer,0,0);
    ctx.globalCompositeOperation = "source-over";
  }
  function update(){
      // if mouse down then 
      if(mouse.but){
        // clear the mask if on the right image
        if(mouse.oldBut === false && mouse.x > 256){
           selectLayer.ctx.clearRect(0,0,w,h);
           mouse.but = false;
        }else{
           // draw the red 
           selectLayer.ctx.fillStyle = "red";
           fillCircle(mouse.x, mouse.y, 10, selectLayer.ctx);
        }
        // update the masked result
        updateSelected();
      }

      // clear the canvas
      ctx.clearRect(0,0,w,h);
      // draw the image
      ctx.drawImage(image,0,0);
      // then draw the marking layer over it with comp overlay
      ctx.globalCompositeOperation = "overlay";
      ctx.drawImage(selectLayer,0,0);
      ctx.globalCompositeOperation = "source-over";

      mouse.oldBut = mouse.but;
      requestAnimationFrame(update);
  }
  requestAnimationFrame(update);
}

const mouse  = {
  x : 0, y : 0, but : false,
  events(e){
    const m = mouse;
    const bounds = canvas.getBoundingClientRect();
    m.x = e.pageX - bounds.left - scrollX;
    m.y = e.pageY - bounds.top - scrollY;
    m.but = e.type === "pointerdown" ? true : e.type === "pointerup" ? false : m.but;
  }
};

document.addEventListener('pointerdown', mouse.events);
document.addEventListener('pointerup', mouse.events);
document.addEventListener('pointermove', mouse.events);

const CImage = (w = 128, h = w) => (c = document.createElement("canvas"),c.width = w,c.height = h, c);
const CImageCtx = (w = 128, h = w) => (c = CImage(w,h), c.ctx = c.getContext("2d"), c);
const fillCircle = (l,y=ctx,r=ctx,c=ctx) =>{if(l.p1){c=y; r=leng(l);y=l.p1.y;l=l.p1.x }else if(l.x){c=r;r=y;y=l.y;l=l.x}c.beginPath(); c.arc(l,y,r,0,Math.PI*2); c.fill()}
Draw on image and the selected parts are shown on the right<br>
Click right image to reset selection<br>
<canvas id="canvas" width=256 height=256></canvas>

Check to run code snippet.



回答3:

You need

import { CropPlugin } from 'ionic-native';

You can look at https://github.com/alexk111/ngImgCrop and https://github.com/jeduan/cordova-plugin-crop