0
votes

This problem only occurs when the image's width and height is the same (square).

I first load an image of varying size on my web page – the image is then scaled to width=304, height=164 where the cropping is done. I need to map the cropping coordinates , height and width on the scaled image and perform the cropping on original image size . I need the cropped output to be the size of the original image. The cropping is done correctly however the coordinates and cropped area seems to be a bit off.

Some images are fine but i had problems with a 5000x5000 image

I am using the following code to crop an image:

scope.saveCrop = function(imageUrl) {

    var image;
    image = new Image();
    image.setAttribute('crossorigin', 'anonymous');
    image.onload = function() {
      var blob, canvas, context, cropHeight, cropWidth, cropX, cropY, formData, ratioX, ratioY, requestHeaders;
      canvas = document.createElement('canvas');
      context = canvas.getContext('2d');
      ratioX = image.naturalWidth / 304;
      ratioY = image.naturalHeight / 164;
      cropX = scope.cropData.x * ratioX;
      cropY = scope.cropData.y * ratioY;
      cropWidth = scope.cropData.w / 304 * image.naturalWidth;
      cropHeight = scope.cropData.h / 164 * image.naturalHeight;
      canvas.width = image.naturalWidth;
      canvas.height = image.naturalHeight;
      context.drawImage(image, cropX, cropY, cropWidth, cropHeight, 0, 0, image.naturalWidth, image.naturalHeight);

image.src = imageUrl

Can you please help me to determine why the cropped output coordinates is incorrect?

I am using the jcrop library

(function() {

  define(['common', 'jquery-lib/jquery.jcrop.min'], function(app) {
    return app.compileProvider.directive('apiImgCrop', function() {
      return {
        restrict: 'E',
        replace: true,
        scope: {
          isartist: '@',
          src: '=',
          selected: '&',
          updated: '&',
          width: '@',
          height: '@'
        },
        link: function(scope, element, attr) {
          var clear, myImg;
          element.before('<link rel="stylesheet" type="text/css" href="/Content/Views/jquery.jcrop.min.css" />');
          myImg = void 0;
          clear = function() {
            if (myImg) {
              myImg.next().remove();
              myImg.remove();
              return myImg = void 0;
            }
          };
          scope.$watch('src', function(newVal) {
            var ngSrc, ratio;
            clear();
            ratio = 0;
            if (scope.isartist) {
              ratio = 4 / 3;
            } else {
              ratio = 16 / 9;
            }
            if (newVal) {
              ngSrc = newVal + '?width=' + scope.width + '&height=' + scope.height + '&crop=auto';
              element.after('<img id="crop-image" crossorigin="anonymous" />');
              myImg = element.next();
              myImg.attr('src', ngSrc);
              return $(myImg).Jcrop({
                aspectRatio: ratio,
                trackDocument: true,
                onChange: function(x) {
                  if (!scope.$$phase) {
                    return scope.$apply(function() {
                      return scope.updated({
                        coords: x
                      });
                    });
                  }
                },
                onSelect: function(x) {
                  if (!scope.$$phase) {
                    return scope.$apply(function() {
                      return scope.selected({
                        coords: x
                      });
                    });
                  }
                }
              });
            }
          });
          return scope.$on('$destroy', clear);
        }
      };
    });
  });
1

1 Answers

0
votes

I don't know that this could help you, but have you tried using ngImgCropExtended ? The library provides some advanced features for cropping image including cropping image with specific aspect ratio. Hope this might help