SPFx Image Editor Sample - Playing with Canvas

Published Mar 31 2021 09:49 AM 1,148 Views
Senior Member

In the year 2020, Microsoft added a new capability to the Image Viewer Web part Resize and Crop. These are excellent features, but I want to try to give the End User more Manipulation Options. I was thinking about Flip and Rotate. First, I tried with CSS it worked, but for me, an Image-Editor should work in every combination of applied manipulations.

So, I started to play with canvas.

Screenshot 2021-03-22 at 21.42.06.png

How HTML canvas  works

Screenshot 2021-03-22 at 20.29.22.png

Screenshot 2021-03-22 at 20.29.33.png

 

The next step is to draw an image to our HTML canvas

 

 

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;"></canvas>
<script>
  const img= new Image()
  img.crossOrigin = "Anonymous";
  img.addEventListener("load", imageReceived, false);
  img.src='https://pnp.github.io/images/hero-parker-p-800.png';

  function imageReceived() {
  const c = document.getElementById("myCanvas");
  const ctx = c.getContext("2d");
  c.width = img.width;
  c.height = img.height;
  ctx.drawImage(img, 0, 0);
  ctx.font = "30px Arial";
  ctx.strokeText("Hello PnP-Community",10,50);
}
</script>

 

 

Parker draw on canvasParker draw on canvas

 

How to Flip such thing

FlipY

 

 

ctx.translate(c.width, 0);
ctx.scale(-1, 1);

 

 

Flip Parker YFlip Parker Y

FlipX

 

 

ctx.translate(0, c.height);
ctx.scale(1, -1);

 

 

Flip Parker XFlip Parker X

Rotate:

To explain rotation, I start with a straightforward Sample

I draw only a Rectangle on a canvas

Screenshot 2021-03-22 at 21.48.21.png

Then I rotate this thing for 20 Degree

Screenshot 2021-03-22 at 21.48.51.png

As you can see the rotation Point is not in the Center of the Canvas. The Rotation Point is at Position 0,0

Screenshot 2021-03-22 at 21.54.42.png

For this sample I want to rotate the Rectange from the center of the Black box. So we have to move center to position 0,0 than the rotation and than move it back to original position. 

 

 Now it looks good, but the edges are out of the canvas. Due to the rotation, the height and width has to be changed. Welcome back to maths class.

To i Combine the previous knowledge with the basic Parker Sample here it is

 

 

const img= new Image()
  img.crossOrigin = "Anonymous";
  img.addEventListener("load", imageReceived, false);
  img.src='https://pnp.github.io/images/hero-parker-p-800.png';

  function imageReceived() {
  const c = document.getElementById("myCanvas");
  const ctx = c.getContext("2d");
  const oldwidth =c.width = img.width;
  const oldheight =c.height = img.height;
  const degree=20;
  const radian=degree*Math.PI/180 //Radian
  
  const a = oldwidth * Math.abs(Math.cos(radian));
  const b =  oldheight * Math.abs(Math.sin(radian));
  const p = oldwidth * Math.abs(Math.sin(radian));
  const q =  oldheight * Math.abs(Math.cos(radian));
  const newwidth = a + b;
  const newheight = p + q;

   const offsetwidth = (newwidth - oldwidth) / 2;
   const offsetheight = (newheight - oldheight) / 2;
    c.width = newwidth;
    c.height = newheight;
  
  ctx.translate(newwidth/2,newheight/2);
  ctx.rotate(radian);
  ctx.translate(-newwidth/2,-newheight/2);
  
  ctx.fillStyle = "#0078d4";
  ctx.fillRect(offsetwidth,offsetheight,oldwidth,oldheight);
  
  ctx.drawImage(img, offsetwidth, offsetheight);
   ctx.font = "30px Arial";
  ctx.strokeText("Hello PnP-Community",offsetwidth+10,offsetheight+50);
  
}

 

 

Screenshot 2021-03-23 at 15.18.24.png

Thank's, Parker to be my Top-Model

Try it sp-dev-fx-webparts/samples/react-image-editor at master · pnp/sp-dev-fx-webparts (github.com)

 

 

%3CLINGO-SUB%20id%3D%22lingo-sub-2232131%22%20slang%3D%22en-US%22%3ESPFx%20Image%20Editor%20Sample%20-%20Playing%20with%20Canvas%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2232131%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%3EIn%20the%20year%202020%2C%20Microsoft%20added%20a%20new%20capability%20to%20the%20Image%20Viewer%20Web%20part%20Resize%20and%20Crop.%20These%20are%20excellent%20features%2C%20but%20I%20want%20to%20try%20to%20give%20the%20End%20User%20more%20Manipulation%20Options.%20I%20was%20thinking%20about%20Flip%20and%20Rotate.%20First%2C%20I%20tried%20with%20CSS%20it%20worked%2C%20but%20for%20me%2C%20an%20Image-Editor%20should%20work%20in%20every%20combination%20of%20applied%20manipulations.%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3ESo%2C%20I%20started%20to%20play%20with%20canvas.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-22%20at%2021.42.06.png%22%20style%3D%22width%3A%20750px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266630iB1ECA3D66EE3DBDA%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-22%20at%2021.42.06.png%22%20alt%3D%22Screenshot%202021-03-22%20at%2021.42.06.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%E2%80%83%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--496427025%22%20id%3D%22toc-hId--496427025%22%3E%3CSPAN%3EHow%20HTML%20canvas%26nbsp%3B%20works%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CP%3E%E2%80%83%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-22%20at%2020.29.22.png%22%20style%3D%22width%3A%20738px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266632i298293D5AEC7AEC2%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-22%20at%2020.29.22.png%22%20alt%3D%22Screenshot%202021-03-22%20at%2020.29.22.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-22%20at%2020.29.33.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266633iF5DE88335FDE019F%2Fimage-size%2Fmedium%3Fv%3Dv2%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-22%20at%2020.29.33.png%22%20alt%3D%22Screenshot%202021-03-22%20at%2020.29.33.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%E2%80%83%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20next%20step%20is%20to%20draw%20an%20image%20to%20our%20HTML%20canvas%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-html%22%3E%3CCODE%3E%3CCANVAS%20id%3D%22myCanvas%22%20width%3D%22200%22%20height%3D%22100%22%20style%3D%22border%3A1px%20solid%20%23d3d3d3%3B%22%3E%3C%2FCANVAS%3E%0A%3CSCRIPT%3E%0A%20%20const%20img%3D%20new%20Image()%0A%20%20img.crossOrigin%20%3D%20%22Anonymous%22%3B%0A%20%20img.addEventListener(%22load%22%2C%20imageReceived%2C%20false)%3B%0A%20%20img.src%3D'https%3A%2F%2Fpnp.github.io%2Fimages%2Fhero-parker-p-800.png'%3B%0A%0A%20%20function%20imageReceived()%20%7B%0A%20%20const%20c%20%3D%20document.getElementById(%22myCanvas%22)%3B%0A%20%20const%20ctx%20%3D%20c.getContext(%222d%22)%3B%0A%20%20c.width%20%3D%20img.width%3B%0A%20%20c.height%20%3D%20img.height%3B%0A%20%20ctx.drawImage(img%2C%200%2C%200)%3B%0A%20%20ctx.font%20%3D%20%2230px%20Arial%22%3B%0A%20%20ctx.strokeText(%22Hello%20PnP-Community%22%2C10%2C50)%3B%0A%7D%0A%3C%2FSCRIPT%3E%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-23%20at%2014.38.34.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266621i69B453DB774451EF%2Fimage-size%2Fmedium%3Fv%3Dv2%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-23%20at%2014.38.34.png%22%20alt%3D%22Parker%20draw%20on%20canvas%22%20%2F%3E%3CSPAN%20class%3D%22lia-inline-image-caption%22%20onclick%3D%22event.preventDefault()%3B%22%3EParker%20draw%20on%20canvas%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EHow%20to%20Flip%20such%20thing%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EFlipY%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-javascript%22%3E%3CCODE%3Ectx.translate(c.width%2C%200)%3B%0Actx.scale(-1%2C%201)%3B%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-23%20at%2014.47.53.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266622iA8FF341BD6DC9B21%2Fimage-size%2Fmedium%3Fv%3Dv2%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-23%20at%2014.47.53.png%22%20alt%3D%22Flip%20Parker%20Y%22%20%2F%3E%3CSPAN%20class%3D%22lia-inline-image-caption%22%20onclick%3D%22event.preventDefault()%3B%22%3EFlip%20Parker%20Y%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EFlipX%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-javascript%22%3E%3CCODE%3Ectx.translate(0%2C%20c.height)%3B%0Actx.scale(1%2C%20-1)%3B%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-23%20at%2014.47.07.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266623i65AFC8A05604564C%2Fimage-size%2Fmedium%3Fv%3Dv2%26amp%3Bpx%3D400%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-23%20at%2014.47.07.png%22%20alt%3D%22Flip%20Parker%20X%22%20%2F%3E%3CSPAN%20class%3D%22lia-inline-image-caption%22%20onclick%3D%22event.preventDefault()%3B%22%3EFlip%20Parker%20X%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3ERotate%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3ETo%20explain%20rotation%2C%20I%20start%20with%20a%20straightforward%20Sample%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EI%20draw%20only%20a%20Rectangle%20on%20a%20canvas%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-22%20at%2021.48.21.png%22%20style%3D%22width%3A%20660px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266624i3712E1A11EB969D6%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-22%20at%2021.48.21.png%22%20alt%3D%22Screenshot%202021-03-22%20at%2021.48.21.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%E2%80%83%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThen%20I%20rotate%20this%20thing%20for%2020%20Degree%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-22%20at%2021.48.51.png%22%20style%3D%22width%3A%20660px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266625iDAC073380A6F6955%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-22%20at%2021.48.51.png%22%20alt%3D%22Screenshot%202021-03-22%20at%2021.48.51.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%E2%80%83%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20you%20can%20see%20the%20rotation%20Point%20is%20not%20in%20the%20Center%20of%20the%20Canvas.%20The%20Rotation%20Point%20is%20at%20Position%200%2C0%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-22%20at%2021.54.42.png%22%20style%3D%22width%3A%20664px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266626iDF164C650C7F26B5%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-22%20at%2021.54.42.png%22%20alt%3D%22Screenshot%202021-03-22%20at%2021.54.42.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EFor%20this%20sample%20I%20want%20to%20rotate%20the%20Rectange%20from%20the%20center%20of%20the%20Black%20box.%20So%20we%20have%20to%20move%20center%20to%20position%200%2C0%20than%20the%20rotation%20and%20than%20move%20it%20back%20to%20original%20position.%E2%80%83%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3E%26nbsp%3BNow%20it%20looks%20good%2C%20but%20the%20edges%20are%20out%20of%20the%20canvas.%20Due%20to%20the%20rotation%2C%20the%20height%20and%20width%20has%20to%20be%20changed.%20Welcome%20back%20to%20maths%20class.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3ETo%20i%20Combine%20the%20previous%26nbsp%3B%3C%2FSPAN%3E%3CSPAN%3Eknowledge%20with%20the%20basic%20Parker%20Sample%20here%20it%20is%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-javascript%22%3E%3CCODE%3Econst%20img%3D%20new%20Image()%0A%20%20img.crossOrigin%20%3D%20%22Anonymous%22%3B%0A%20%20img.addEventListener(%22load%22%2C%20imageReceived%2C%20false)%3B%0A%20%20img.src%3D'https%3A%2F%2Fpnp.github.io%2Fimages%2Fhero-parker-p-800.png'%3B%0A%0A%20%20function%20imageReceived()%20%7B%0A%20%20const%20c%20%3D%20document.getElementById(%22myCanvas%22)%3B%0A%20%20const%20ctx%20%3D%20c.getContext(%222d%22)%3B%0A%20%20const%20oldwidth%20%3Dc.width%20%3D%20img.width%3B%0A%20%20const%20oldheight%20%3Dc.height%20%3D%20img.height%3B%0A%20%20const%20degree%3D20%3B%0A%20%20const%20radian%3Ddegree*Math.PI%2F180%20%2F%2FRadian%0A%20%20%0A%20%20const%20a%20%3D%20oldwidth%20*%20Math.abs(Math.cos(radian))%3B%0A%20%20const%20b%20%3D%20%20oldheight%20*%20Math.abs(Math.sin(radian))%3B%0A%20%20const%20p%20%3D%20oldwidth%20*%20Math.abs(Math.sin(radian))%3B%0A%20%20const%20q%20%3D%20%20oldheight%20*%20Math.abs(Math.cos(radian))%3B%0A%20%20const%20newwidth%20%3D%20a%20%2B%20b%3B%0A%20%20const%20newheight%20%3D%20p%20%2B%20q%3B%0A%0A%20%20%20const%20offsetwidth%20%3D%20(newwidth%20-%20oldwidth)%20%2F%202%3B%0A%20%20%20const%20offsetheight%20%3D%20(newheight%20-%20oldheight)%20%2F%202%3B%0A%20%20%20%20c.width%20%3D%20newwidth%3B%0A%20%20%20%20c.height%20%3D%20newheight%3B%0A%20%20%0A%20%20ctx.translate(newwidth%2F2%2Cnewheight%2F2)%3B%0A%20%20ctx.rotate(radian)%3B%0A%20%20ctx.translate(-newwidth%2F2%2C-newheight%2F2)%3B%0A%20%20%0A%20%20ctx.fillStyle%20%3D%20%22%230078d4%22%3B%0A%20%20ctx.fillRect(offsetwidth%2Coffsetheight%2Coldwidth%2Coldheight)%3B%0A%20%20%0A%20%20ctx.drawImage(img%2C%20offsetwidth%2C%20offsetheight)%3B%0A%20%20%20ctx.font%20%3D%20%2230px%20Arial%22%3B%0A%20%20ctx.strokeText(%22Hello%20PnP-Community%22%2Coffsetwidth%2B10%2Coffsetheight%2B50)%3B%0A%20%20%0A%7D%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Screenshot%202021-03-23%20at%2015.18.24.png%22%20style%3D%22width%3A%20878px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F266627i97EE7597385508C5%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22Screenshot%202021-03-23%20at%2015.18.24.png%22%20alt%3D%22Screenshot%202021-03-23%20at%2015.18.24.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%E2%80%83%3C%2FP%3E%0A%3CP%3EThank's%2C%20Parker%20to%20be%20my%20Top-Model%3C%2FP%3E%0A%3CP%3ETry%20it%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fpnp%2Fsp-dev-fx-webparts%2Ftree%2Fmaster%2Fsamples%2Freact-image-editor%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Esp-dev-fx-webparts%2Fsamples%2Freact-image-editor%20at%20master%20%C2%B7%20pnp%2Fsp-dev-fx-webparts%20(github.com)%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-2232131%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%3EMicrosoft%20added%20a%20new%20capability%20to%20the%20Image%20Viewer%20Web%20part%20Resize%20and%20Crop.%20These%20are%20excellent%20features%2C%20but%20you%20can%20learn%20here%20how%20to%20give%20the%20End%20User%20more%20Manipulation%20Options.%20%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-2232131%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EHow%20to%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Co-Authors
Version history
Last update:
‎Mar 31 2021 09:48 AM
Updated by: