Search code examples
javascripthtmliphonecanvaskineticjs

KineticJs: How to import iPhone Retina Images taken by Camera?


I tried to import camera images from iPhone5 retinal iOs7. The following image shows the problem. The stage is the yellow filled rectangle and the image at the top is the image which is imported into the stage.

enter image description here

I created a Jsfiddle to demonstrate the problem here: http://jsfiddle.net/confile/45zdm/

I think that there are two problems the first one is that the pixel ration of 2 might be a problem. When I set

image.height(stage.height())

The image takes only half the height of the stage. This is only the can for images that are taken with the camera. When you import images from screen shots it works fine as I demonstrated in the following image:

enter image description here

The second problem is that images from camera are in the wrong angle so you have to take the exif orientation property into account.

How can I import retina images from iPhone camera into KineticJs to be displayed correctly?


Solution

  • I want to repost my comment from github: https://github.com/ericdrowell/KineticJS/pull/654#issuecomment-40284966

    Use fixed canvas instead of image.

    // detect scale ratio
    function detectVerticalSquash(img) {
      var iw = img.width, ih = img.height;
      var canvas = document.createElement('canvas');
      canvas.width = 1;
      canvas.height = ih;
      var ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0);
      var data = ctx.getImageData(0, 0, 1, ih).data;
      // search image edge pixel position in case it is squashed vertically.
      var sy = 0;
      var ey = ih;
      var py = ih;
      while (py > sy) {
          var alpha = data[(py - 1) * 4 + 3];
          if (alpha === 0) {
              ey = py;
          } else {
              sy = py;
          }
          py = (ey + sy) >> 1;
      }
      var ratio = (py / ih);
      return (ratio===0)?1:ratio;
    }
    
    // create canvas to replace with image
    function generateCanvas(image){
        var canvas = document.createElement('canvas');
        var context = canvas.getContext('2d');
        canvas.width = image.width;
        canvas.height = image.height;
        var vertSquashRatio = detectVerticalSquash(image);
        context.drawImage(image, 0, 0, 
                           image.width, image.height / vertSquashRatio);
        return(canvas);
    }
    
    var img = new Image();
    img.onload = function() {
      var stage = new Kinetic.Stage({
          container: 'con',
          width: 1000,
          height: 1000
      });
      var layer = new Kinetic.Layer();
      stage.add(layer);
      var image = new Kinetic.Image({
        image : generateCanvas(img),
        width : 200,
        height : 200,
        draggable : true
      });
      layer.add(image);
      layer.draw();
    }
    img.src = 'diana2.jpg';