首页 > 解决方案 > 从页面截取图像

问题描述

我想用 Angular 6+ 构建图像截图功能。我的要求是 -

  1. 在网页上,用户可以使用鼠标拖动选择一个区域(矩形格式)。
  2. 捕获所选区域并在剪贴板中添加为图像。
  3. 当用户执行“从剪贴板复制”等操作时,将检索上次保存到剪贴板的图像。

提前感谢您的意见。

标签: angular

解决方案


I have implemented the solution though its not 100%, but can serve the purpose ;) . adding my solution, may be it can help someone or someone can suggest improvement.

Here is my solution -

Implemented the solution using 2 angular lib a. html2canvas - to capture the screen shot of your screen or target html tag. b. angular-cropperjs - crop the image (htl2cavas out will be input for cropping). Also you have to add dependency cropperjs which is used by angular-cropperjs.

Solution code -

------------Template code for html2canvas -------------------

<div class="row">
    <div  #screen>
  // add you code ()
</div>

---------------- component code or.ts file code --------------- @ViewChild('screen') screen: ElementRef;

captureView() {
    html2canvas(this.screen.nativeElement).then(canvas => {
      this.imageUrl = canvas.toDataURL('image/png');
    });
  }

// capture image and assign value to variable, which can be input to angular-cropper component.

--------------Template code for angular-cropperjs -------------------------------

<angular-cropper #angularCropper [cropperOptions]="angularCropperConfig" [imageUrl]="imageUrl" *ngIf="imageUrl"></angular-cropper>

-----------Component code for angular-cropperjs -----------------------------

@ViewChild('angularCropper') public angularCropper: CropperComponent;
  angularCropperConfig = {
    aspectRatio : 16/9,
    dragMode : 'drag',
    background : false,
    movable: true,
    rotatable : false,
    scalable: true,
    zoomable: false,
    viewMode: 1,
    checkImageOrigin : true,
    checkCrossOrigin: true
  };


selectImage() { 
cropImageOutput = this.angularCropper.cropper.getCroppedCanvas().toDataURL().toString());
  }

// this out will will be used where you want to paste cropped image

------------------- final code where you want to use it -----------------------

template code ---

<div>
              <canvas style="border:1px solid grey;" id="mycanvas"></canvas>
              </div>
              <div class="col-xl-1 col-md-1 col-xs-12 pull-left">
                <button mat-raised-button color="primary" (click)="addImage()">add image</button>
              </div>

component code -

addImage(cropImageOutput ) {
const imageBlob = convertBase64ToBlob(cropImageOutput );
 if (imageBlob) {
              const canvas = document.getElementById('mycanvas');
              const ctx = canvas.getContext('2d');

              // Create an image to render the blob on the canvas
              const img = new Image();

              // Once the image loads, render the img on the canvas
              img.onload = function () {
                // Update dimensions of the canvas with the dimensions of the image
                canvas.width = this.width;
                canvas.height = this.height;

                // Draw the image
                ctx.drawImage(img, 0, 0);
              };

              // Crossbrowser support for URL
              const URLObj = window.URL || window.webkitURL;

              // Creates a DOMString containing a URL representing the object given in the parameter
              // namely the original Blob
              img.src = URLObj.createObjectURL(imageBlob);
            }
  }

/**
 * CONVERT BASE64 TO BLOB
 * @param Base64Image Pass base64 image data to convert into the blob
 */
function convertBase64ToBlob(base64Image: string) {
  // SPLIT INTO TWO PARTS
  const parts = base64Image.split(';base64,');
  // HOLD THE CONTENT TYPE
  const imageType = parts[0].split(':')[1];
  // DECODE BASE64 STRING
  const decodedData = window.atob(parts[1]);
  // CREATE UNIT8ARRAY OF SIZE SAME AS ROW DATA LENGTH
  const uInt8Array = new Uint8Array(decodedData.length);
  // INSERT ALL CHARACTER CODE INTO UINT8ARRAY
  for (let i = 0; i < decodedData.length; ++i) {
    uInt8Array[i] = decodedData.charCodeAt(i);
  }
  // RETURN BLOB IMAGE AFTER CONVERSION
  return new Blob([uInt8Array], { type: imageType });
}

推荐阅读