cordova-plugin-camera-preview icon indicating copy to clipboard operation
cordova-plugin-camera-preview copied to clipboard

picture size is different to the seems in the viewer

Open mangel1196 opened this issue 8 years ago • 28 comments

Hi.

When the viewer is open looks a size but when the picture is taken have a different size ( more big )

Thanks

mangel1196 avatar Mar 08 '17 14:03 mangel1196

takePicture takes a photo using the camera not the preview. This allows for maximum megapixels for image.

I wonder if it would be beneficial to have the option to capture images using the camera or preview?

westonganger avatar Mar 08 '17 15:03 westonganger

the trouble is at the moment of watch a preliminar view then the picture change a lot and doesn't looks like i see in the viewer, and at the moment of send all the pictures the size is much bigger an the transaction take a lot of time, in a preview version, the plugin gets the 2 sizes, i don't know if that is possible now to be added like a little patch

mangel1196 avatar Mar 08 '17 15:03 mangel1196

If you want the picture size to match the preview size, you can pass the size of the preview as options to the takePicture method:

var previewWidth = ... get the width of the preview; var previewHeight = ... get the height of the preview; CameraPreview.takePicture({width: previewWidth, height: previewHeight}, function(base64Data) {});

Note that CameraPreview.takePicture uses actual pixels for width and height. On mobile devices, the preview width and height are often defined in css pixels. Mutiply width and height by the device pixelRatio if you want preview and picture to be the same resolution.

anneb avatar Mar 09 '17 09:03 anneb

Hi @anneb for your answer but now i try it and it still the same size:

look my code, i not see anything especial.

i define the size like a little square for watch the change and nothing


CameraPreview.takePicture(
        {
            width: 20,
            height: 20
        },
        function (result) {
            
            console.log(result); 
            $("#contenedorCamara").css({
                "background-image": "url( data:image/jpeg;base64," + result[0] + ")",
                "background-size": "100% auto"
            });
            $("#previewFoto").attr("src", "data:image/jpeg;base64," + result[0]);
        });

P.S: sorry for my spanglish

mangel1196 avatar Mar 09 '17 15:03 mangel1196

On Android, I did CameraPreview.takePicture({width: 20, height: 20}, function (result) {});

and got an image of 120 x 160 pixels

Reason:

  • the plugin first checks the preview aspect ratio
  • then it scans all supported pictureSizes that are closest to the preview aspect ratio
  • then is selects the supported pictureSize closest to width and height

Normally, a device will not support square pictures of 20 x 20 pixels. For my device and preview and portrait orientation, the closest supported picture size with the correct aspect ratio is 120 x 160 pixels.

In your example you seem to be stretching to the image to 100% of the background width? This way, you cannot easily see the actual resulting image natural width and height?

anneb avatar Mar 09 '17 17:03 anneb

So, thanks for answer but i think that is my develop device, this take a bad picture, in other device works perfectly, then i have a new question, ¿maybe this plugin have some dependency with the hardware?.

and the line of the background just is for a div that show a preview.

mangel1196 avatar Mar 09 '17 19:03 mangel1196

Try this..

    constructor(private nav: NavController, private zone:NgZone){
    
    CameraPreview.setOnPictureTakenHandler().subscribe((d)=>{

     (<HTMLImageElement>document.getElementById('previewPicture')).src = d[0];

    //  (<HTMLImageElement>document.getElementById('originalPicture')).src= d[1];

       CameraPreview.stopCamera();

       console.log('d',d);

     });

          this.zone.run(() => {

          this.getWidth = window.innerWidth;

         this.getHeight = window.innerHeight;

    });
  
        console.log('width',this.getWidth);
    
       this.calcWidth = this.getWidth - 80;  // Calculate the width of device and substract 80 from device width;
       
         console.log('calc width',this.calcWidth);  
   
}

Ghayyas avatar Mar 12 '17 21:03 Ghayyas

how to get same resolution like startcamera in takepicture

aliwaqassi avatar Mar 20 '17 12:03 aliwaqassi

takePicture({width: camwidth, height: camheight}, successhandler, errorhandler);

where camwidth and camheight are the same as the width and height used with startCamera. Note that takePicture chooses the nearest supported resolution, wich may not be exactly the same resolution. You can use getSupportedPictureSizes to get the list of supported resolutions and select one of these for startCamera.

anneb avatar Mar 20 '17 13:03 anneb

I gave the same width and height from startCamera to takePicture , my images are still having the full picture instead of camera preview picture.

kchenna avatar Mar 20 '17 13:03 kchenna

are the width and height of your preview in the list of supported picture sizes?

anneb avatar Mar 20 '17 13:03 anneb

Yes ,I tried with height 480 and width 640 and it supported picture size

kchenna avatar Mar 20 '17 14:03 kchenna

this problem came when this plugin update i have one old version of that plugin that is working fine , now few days ago i added update plugin then this issue came, any body have solution please share your experience with us, thanks

aliwaqassi avatar Mar 20 '17 15:03 aliwaqassi

Tried to replicate your problem. On Android, using git master from remote https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview, called

CameraPreview.takePicture({width: 640, height: 480}, _app.takePictureHandler, function(reason)
                  {
                      _app.showMessage(reason);
                  });

Result is image naturalWidth 640px x naturalHeight 480px.

  • are you passing in width or maxWidth, height of maxHeight? (you should use width/height)?
  • are you using Android or iOS?
  • how do you verify the image result (I am using chrome://inspect, view image element, inspect natural width and height)?

anneb avatar Mar 20 '17 15:03 anneb

Result is image naturalWidth 640px x naturalHeight 480px.

are you passing in width or maxWidth, height of maxHeight? (you should use width/height)? I am using width and height are you using Android or iOS? Android how do you verify the image result (I am using chrome://inspect, view image element, inspect natural width and height)? by chrome://inspect but not verifying the width and height by seeing itself clearly it covers more height than camera preview

kchenna avatar Mar 20 '17 16:03 kchenna

I am using IOS this problem came on IOS for me

aliwaqassi avatar Mar 20 '17 18:03 aliwaqassi

@kchenna: what is the css for the image? It is easy to have an image with correct width/height that is layed out incorrectly. Also note that on many devices the css width / height are not the same as pixel width and height. There may be a device pixel ratio between physical pixels and logical pixels. Please explain exactly your problem: if the natural width and height are as requested, but the image is not displayed correctly, I do not see how that is a problem of the plugin.

@aliwaqassi on iOS I think the plugin should scale the image to the requested width / height (NOT maxWidth/ maxHeight). Exactly what width and height are you requesting and what naturalWidth and naturalHeight is returned?

anneb avatar Mar 20 '17 20:03 anneb

This is my code

CameraPreview.startCamera

CameraPreview.startCamera({x: 0, y: 0, width: window.screen.width, height: window.screen.height, camera: "front", toBack: true, tapPhoto: true, previewDrag: false});

CameraPreview.takePicture

CameraPreview.takePicture({width: window.screen.width, height: window.screen.height,quality: 100},function(base64PictureData)
        {
              /*
                base64PictureData is base64 encoded jpeg image. Use this data to store to a file or upload.
                Its up to the you to figure out the best way to save it to disk or whatever for your application.
              */
                var imageSrcData = 'data:image/jpeg;base64,' +base64PictureData[0];
                $('#device_results_instrument').show();
                $('#device_results_instrument').html('<img width="'+window.screen.width+'" height="'+window.screen.height+'" src="'+imageSrcData+'"/>');
                CameraPreview.hide();
              // One simple example is if you are going to use it inside an HTML img src attribute then you would do the following:
              
        });```

aliwaqassi avatar Mar 20 '17 20:03 aliwaqassi

@anneb This is what i've set . CameraPreview.startCamera({x: 0, y: 0, width: 360, height: 270, camera: "back", toBack: true, tapPhoto: false, previewDrag: false}); window.CameraPreview.takePicture({width:360,height:270,quality:100},(base64pictureData)=>setImageIntoThumbnail(base64pictureData));

kchenna avatar Mar 22 '17 13:03 kchenna

visually when we see the taken image , the width of the image is correct but height is covered with full view irrespective of camera preview .

kchenna avatar Mar 22 '17 13:03 kchenna

I am also seeing this problem on iOS with the latest master.

Width and height of startCamera() are set to window.screen.width and window.screen.height, which are 375x667 on an iPhone6 (aspect ratio ~.562).

When getting supported image sizes via getSupportedPictureSizes(), I see 3264x2448, 1280x720, and 3264x1836.

Regardless of what I set the takePicture() height/width to, I get a photo with an aspect ratio of .75 (which correlates with the aspect ratio for the support size 2448x3264). I want the preview width of 1836x3264, the aspect ratio of the preview, as precision of the photo is important for my app.

I've even tried manually setting the takePicture width/height to 1836x3264 to test it, but the resulting photo is still 2448x3264.

Any suggestions?

mikewagz avatar May 01 '17 16:05 mikewagz

Yes we definitely need a way to specify whether you want the photo using native aspect ratio or photo using preview.

The problem with taking a photo using the preview is that it can only take a photo the same resolution as your screen, not your camera. This is why we switched it to native resolution but it came with all this confusion of aspect ratios and pixels etc.

We also need to see about a way to get a photo in the requested dimensions. This could either be part of the API that was missed or it may require us to crop the image.

In the meantime you are probably going to have to crop the image within your app if you really require a specific dimensions that doesnt match a supported size.

westonganger avatar May 01 '17 16:05 westonganger

I was able to find a solution that may help anyone who is having issues with the camera preview image & the image that is displayed discrepancy. Its a method that creates and sort of background-cover effect for your captured image. Below I will post the code, the original stack overflow as well as a demo. Good Luck!

All credit for this code goes to Ken Fyrstenberg Nilsen.

DEMO http://jsfiddle.net/epistemex/yqce3tuw/1/

SOURCE https://stackoverflow.com/questions/21961839/simulation-background-size-cover-in-canvas

draw(ctx: CanvasRenderingContext2D) { this.drawImageProp(ctx, this.image, 0, 0, ctx.canvas.width, ctx.canvas.height, 0.5, 0.5); }

` drawImageProp(ctx, img, x, y, w, h, offsetX, offsetY) {

if (arguments.length === 2) {
    x = y = 0;
    w = ctx.canvas.width;
    h = ctx.canvas.height;
}

console.log(offsetX);
console.log(offsetY);

/// default offset is center
offsetX = typeof offsetX === 'number' ? offsetX : 0.5;
offsetY = typeof offsetY === 'number' ? offsetY : 0.5;

/// keep bounds [0.0, 1.0]
if (offsetX < 0) offsetX = 0;
if (offsetY < 0) offsetY = 0;
if (offsetX > 1) offsetX = 1;
if (offsetY > 1) offsetY = 1;

var iw = img.width,
    ih = img.height,
    r = Math.min(w / iw, h / ih),
    nw = iw * r,   /// new prop. width
    nh = ih * r,   /// new prop. height
    cx, cy, cw, ch, ar = 1;

/// decide which gap to fill    
if (nw < w) ar = w / nw;
if (nh < h) ar = h / nh;
nw *= ar;
nh *= ar;

/// calc source rectangle
cw = iw / (nw / w);
ch = ih / (nh / h);

cx = (iw - cw) * offsetX;
cy = (ih - ch) * offsetY;

/// make sure source rectangle is valid
if (cx < 0) cx = 0;
if (cy < 0) cy = 0;
if (cw > iw) cw = iw;
if (ch > ih) ch = ih;

/// fill image in dest. rectangle
ctx.drawImage(img, cx, cy, cw, ch,  x, y, w, h);

}`

Now you can call it like this:

drawImageProp(ctx, image, 0, 0, width, height);

and it will scale the image proportionally to fit inside in that container.

Use the two last parameters to offset the image:

var offsetX = 0.5; // center x var offsetY = 0.5; // center y drawImageProp(ctx, image, 0, 0, width, height, offsetX, offsetY);

#311 #299 #221

jamesdeantv avatar Jun 28 '17 19:06 jamesdeantv

@mikewagz did you find a solution? I have the same issue. I keep seeing the camera preview in one way, and the actual picture of a different size (zoomed)

AlexWebYourmind avatar Aug 26 '17 20:08 AlexWebYourmind

Any updates?

yuricamara avatar Apr 09 '19 18:04 yuricamara

Still facing this issue , any one found an effective solution or workaround ?

Ahmed-Abdelftah avatar Jun 30 '21 15:06 Ahmed-Abdelftah

I would also like an update on this

aidadenisa avatar Oct 01 '21 12:10 aidadenisa

+1 IOS images have different resolution than the preview

Fourie-r avatar Nov 26 '21 08:11 Fourie-r