question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TakePhoto is not cropped as configured

See original GitHub issue

I run my camera preview with a long rectagle:

cameraPreviewOpts: CameraPreviewOptions = {
    x: (window.screen.width-150)/2,
    y: window.screen.height*0.05,
    width: 150,
    height: window.screen.height*0.9,
    camera: 'rear',
    tapPhoto: false,
    tapToFocus: true,
    previewDrag: true,
    toBack: false,
    alpha: 1
  };

This is good, but when I take a picture of it, the picture has a totally different dimension, even when the configuration is the same:

   const pictureOpts: CameraPreviewPictureOptions = {
      width: 150,
      height: window.screen.height*0.9,
      quality: 100
    };
    that.cameraPreview.takePicture(pictureOpts).then((imageData) => {
      that.picture = 'data:image/jpeg;base64,' + imageData;
    }, (err) => {

This is the camera ON (this is how I want it) cameraon

This is the picture it takes finalpic

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:10

github_iconTop GitHub Comments

8reactions
youraliencommented, Jul 13, 2018

To attempt to crop the image to match what is seen in the Image Preview, I tried replicating the iOS source code on how the image preview is constructed, using Javascript.

@westonganger What kind of PR would be best to share this knowledge? Should this helper code be included in the README.md with the takePicture documentation?

Here is code I used to take the picture and crop it appropriately.

    // assuming I have a DOM element that is the same size and placement as my desired camera preview
    let previewOverlay = document.getElementById('previewOverlay');
    let rect = previewOverlay.getBoundingClientRect();

    // initialize the camera
    CameraPreview.startCamera({
      x: rect.left, y: rect.top, width: rect.width, height: rect.height, camera: "front",
      tapPhoto: true, previewDrag: false, toBack: true});

    // take the photo and use the cropping function
    CameraPreview.takePicture(function(imgData){
      b64CropLikeCordova(imgData, rect.width, rect.height, function(croppedImgUrl) {
        let imagePreview = $(".fileinput-preview");
        imagePreview.attr('src', croppedImgUrl);
      });
    });

Here is the implementation I wrote

/**
 * Crop a base64 string image given a cropping rectangle, in the same way that
 * the iOS cordova-plugin-camera-preview creates its preview image.
 * See captureOutput function src/ios/CameraRendererController.m of
 * https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview
 * for details on how the image preview is created.
 * Code adapted by github @youralien
 * 
 * @param base64PictureData {String} Pure base64 string without contentType
 * @param rect_width {Number} Preview rectangle width
 * @param rect_height {Number} Preview rectangle height
 * @param callback {Function}
 * @see http://blog.mathocr.com/2017/06/09/camera-preview-with-cordova.html
 * @return base64imageURL
 */
//
function b64CropLikeCordova(base64PictureData, rect_width, rect_height, callback) {

  // image will contain ORIGINAL image
  let image = new Image();

  // image will contain CROPPED image
  let canvas = document.createElement('canvas');
  let ctx = canvas.getContext('2d');

  // Load original image into image element
  image.src = 'data:image/jpeg;base64,' + base64PictureData;
  image.onload = function(){

    let scaleHeight = rect_height/image.height;
    let scaleWidth = rect_width/image.width;

    let scale;
    let x_img_units;
    let y_img_units;
    if (scaleHeight < scaleWidth) {
      scale = scaleWidth;
      x_img_units = 0;
      y_img_units = (image.height - (rect_height / scale)) / 2;
    } else {
      scale = scaleHeight;
      x_img_units = (image.width - (rect_width / scale)) / 2;
      y_img_units = 0;
    }

    let rect_width_img_units = rect_width / scale;
    let rect_height_img_units = rect_height / scale;

    // Set canvas size equivalent to interpolated rectangle size
    canvas.width = rect_width_img_units;
    canvas.height = rect_height_img_units;

    ctx.drawImage(image,
      x_img_units, y_img_units,                       // Start CROPPING from (x_img_units, y_img_units).
      rect_width_img_units, rect_height_img_units,    // Crop interpolated rectangle
      0, 0,                                           // Place the result at 0, 0 in the canvas,
      rect_width_img_units, rect_height_img_units);   // Crop interpolated rectangle

    // Get base64 representation of cropped image
    let cropped_img_base64 = canvas.toDataURL();

    // Now we are ready to send cropped image TO SERVER
    callback(cropped_img_base64);

    return cropped_img_base64;
  };
}

Testing: This was tested with iPhone 6s, with the default front-facing camera image size (1280x960) and default back-facing image size (4032 x 3024).

1reaction
sardapvcommented, Aug 13, 2020

@youralien you are an angel … tysm 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Android: Take Picture, then immediately do crop w/o needing ...
i have one question with this solution, I have a custom view setup when I am in the camera activity. Will I be...
Read more >
ImagePicker - Expo Documentation
You can configure expo-image-picker using its built-in config plugin if you use ... Cropping multiple images is not supported - this option is...
Read more >
ESP32-CAM Take Photo and Save to MicroSD Card
Learn how to take photos with the ESP32-CAM board and save them to a microSD card using Arduino IDE. We'll be using the...
Read more >
Taking still photos with getUserMedia() - Web APIs | MDN
This article shows how to use navigator.mediaDevices.getUserMedia() to access the camera on a computer or mobile phone with getUserMedia() ...
Read more >
Take a picture using the camera - Flutter documentation
Warning: If you do not initialize the CameraController , you cannot use the ... You can use the CameraController to take pictures using...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found