{"action":"created","issue":{"url":"https://api.github.com/repos/szimek/signature_pad/issues/49","labels_url":"https://api.github.com/repos/szimek/signature_pad/issues/49/labels{/name}","comments_url":"https://api.github.com/repos/szimek/signature_pad/issues/49/comments","events_url":"https://api.github.com/repos/szimek/signature_pad/issues/49/events","html_url":"https://github.com/szimek/signature_pad/issues/49","id":29108215,"number":49,"title":"Consider option to remove blank space around signature","user":{"login":"efc","id":604967,"avatar_url":"https://avatars.githubusercontent.com/u/604967?v=3","gravatar_id":"","url":"https://api.github.com/users/efc","html_url":"https://github.com/efc","followers_url":"https://api.github.com/users/efc/followers","following_url":"https://api.github.com/users/efc/following{/other_user}","gists_url":"https://api.github.com/users/efc/gists{/gist_id}","starred_url":"https://api.github.com/users/efc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/efc/subscriptions","organizations_url":"https://api.github.com/users/efc/orgs","repos_url":"https://api.github.com/users/efc/repos","events_url":"https://api.github.com/users/efc/events{/privacy}","received_events_url":"https://api.github.com/users/efc/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":14,"created_at":"2014-03-10T16:12:27Z","updated_at":"2015-12-18T19:29:59Z","closed_at":"2015-11-10T21:20:35Z","body":"I need to use the sig image later in my app and the blank space around the sig can be a bit of a pain. I added an option to remove this blank space so that the image returned when I get the data is the cropped signature. I'm not sure if this would be useful to others, and I am not able to git at the moment, so I'll just offer it here in case it proves helpful.\r\n\r\n```javascript\r\n\tSignaturePad.prototype.removeBlanks = function () {\r\n\t\tvar imgWidth = this._ctx.canvas.width;\r\n\t\tvar imgHeight = this._ctx.canvas.height;\r\n\t\tvar imageData = this._ctx.getImageData(0, 0, imgWidth, imgHeight),\r\n\t\tdata = imageData.data,\r\n\t\tgetAlpha = function(x, y) {\r\n\t\t\treturn data[(imgWidth*y + x) * 4 + 3]\r\n\t\t},\r\n\t\tscanY = function (fromTop) {\r\n\t\t\tvar offset = fromTop ? 1 : -1;\r\n\t\t\t\r\n\t\t\t// loop through each row\r\n\t\t\tfor(var y = fromTop ? 0 : imgHeight - 1; fromTop ? (y < imgHeight) : (y > -1); y += offset) {\r\n\t\t\t\t\r\n\t\t\t\t// loop through each column\r\n\t\t\t\tfor(var x = 0; x < imgWidth; x++) {\r\n\t\t\t\t\tif (getAlpha(x, y)) {\r\n\t\t\t\t\t\treturn y;                        \r\n\t\t\t\t\t}      \r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn null; // all image is white\r\n\t\t},\r\n\t\tscanX = function (fromLeft) {\r\n\t\t\tvar offset = fromLeft? 1 : -1;\r\n\t\t\t\r\n\t\t\t// loop through each column\r\n\t\t\tfor(var x = fromLeft ? 0 : imgWidth - 1; fromLeft ? (x < imgWidth) : (x > -1); x += offset) {\r\n\t\t\t\t\r\n\t\t\t\t// loop through each row\r\n\t\t\t\tfor(var y = 0; y < imgHeight; y++) {\r\n\t\t\t\t\tif (getAlpha(x, y)) {\r\n\t\t\t\t\t\treturn x;                        \r\n\t\t\t\t\t}      \r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn null; // all image is white\r\n\t\t};\r\n\t\t\t\r\n\t\tvar cropTop = scanY(true),\r\n\t\tcropBottom = scanY(false),\r\n\t\tcropLeft = scanX(true),\r\n\t\tcropRight = scanX(false);\r\n\t\t\r\n\t\tvar relevantData = this._ctx.getImageData(cropLeft, cropTop, cropRight-cropLeft, cropBottom-cropTop);\r\n\t\tthis._canvas.width = cropRight-cropLeft;\r\n\t\tthis._canvas.height = cropBottom-cropTop;\r\n\t\tthis._ctx.clearRect(0, 0, cropRight-cropLeft, cropBottom-cropTop);\r\n\t\tthis._ctx.putImageData(relevantData, 0, 0);\r\n\t};\r\n```\r\n\r\nFYI, credit for most of this code goes to http://stackoverflow.com/questions/12175991/crop-image-white-space-automatically-using-jquery\r\n\r\nI imagine my need for this feature also grows from my using signature_pad on a larger tablet instead of a phone-size device."},"comment":{"url":"https://api.github.com/repos/szimek/signature_pad/issues/comments/165877445","html_url":"https://github.com/szimek/signature_pad/issues/49#issuecomment-165877445","issue_url":"https://api.github.com/repos/szimek/signature_pad/issues/49","id":165877445,"user":{"login":"mikemclin","id":1570155,"avatar_url":"https://avatars.githubusercontent.com/u/1570155?v=3","gravatar_id":"","url":"https://api.github.com/users/mikemclin","html_url":"https://github.com/mikemclin","followers_url":"https://api.github.com/users/mikemclin/followers","following_url":"https://api.github.com/users/mikemclin/following{/other_user}","gists_url":"https://api.github.com/users/mikemclin/gists{/gist_id}","starred_url":"https://api.github.com/users/mikemclin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mikemclin/subscriptions","organizations_url":"https://api.github.com/users/mikemclin/orgs","repos_url":"https://api.github.com/users/mikemclin/repos","events_url":"https://api.github.com/users/mikemclin/events{/privacy}","received_events_url":"https://api.github.com/users/mikemclin/received_events","type":"User","site_admin":false},"created_at":"2015-12-18T19:29:59Z","updated_at":"2015-12-18T19:29:59Z","body":"The `removeBlanks` method simply resizes your canvas element.  So, after you call it and submit your data to wherever, you need to resize your canvas back to normal size.  Here is how I accomplished it in Angular.  I know you probably aren't using Angular, but maybe this will give you an idea of how to potentially tack this problem...\r\n\r\nIn this implementation, a button triggers the `submit()` method, which trims the canvas, saves the data, clears the canvas, and then resizes the canvas.  The same function that is used to size the canvas on page load, is re-used to size after saving the data.\r\n\r\nHope this helps...\r\n\r\n### Javascript\r\n\r\n```js\r\nangular\r\n    .module('app')\r\n    .directive('psSignature', psSignature);\r\n\r\n  function psSignature($window, $timeout) {\r\n    return {\r\n      restrict: 'E',\r\n      scope: {\r\n        onCancel: '&',\r\n        onSubmit: '&',\r\n        submitting: '='\r\n      },\r\n      templateUrl: 'widgets.signature',\r\n      link: function (scope, element, attrs) {\r\n        var canvas = element.find('canvas')[0];\r\n        var canvasWrapper = element.find('.signature__body')[0];\r\n        var signaturePad = new SignaturePad(canvas, {onEnd: makeDirty});\r\n        var dirty = false;\r\n\r\n        scope.cancel = scope.onCancel;\r\n        scope.clear = clear;\r\n        scope.submit = submit;\r\n        scope.isDirty = isDirty;\r\n        scope.showCancel = showCancel;\r\n\r\n        activate();\r\n\r\n        ////////////\r\n\r\n        function activate() {\r\n          addListeners();\r\n          $timeout(resizeCanvas, 500);\r\n        }\r\n\r\n        function addListeners() {\r\n          // Add\r\n          angular.element($window).on('resize', resizeCanvas);\r\n          // Clean up\r\n          scope.$on('$destroy', function () {\r\n            angular.element($window).off('resize', resizeCanvas);\r\n          });\r\n        }\r\n\r\n        function makeDirty() {\r\n          scope.$apply(function () {\r\n            dirty = true;\r\n          });\r\n        }\r\n\r\n        function clear() {\r\n          signaturePad.clear();\r\n          dirty = false;\r\n        }\r\n\r\n        function submit() {\r\n          signaturePad.removeBlanks();\r\n          scope.onSubmit({contents: signaturePad.toDataURL()});\r\n          clear();\r\n          resizeCanvas();\r\n        }\r\n\r\n        function isDirty() {\r\n          return dirty;\r\n        }\r\n\r\n        function showCancel() {\r\n          return !!(attrs.onCancel);\r\n        }\r\n\r\n        function resizeCanvas() {\r\n          canvas.width = canvasWrapper.offsetWidth;\r\n          canvas.height = canvasWrapper.offsetHeight;\r\n        }\r\n      }\r\n    };\r\n  }\r\n```\r\n\r\n### HTML\r\n\r\n```html\r\n<div class=\"signature\">\r\n    <div class=\"signature__toolbar\">\r\n        <div class=\"signature__cancel\">\r\n            <button ng-click=\"cancel()\" ng-show=\"showCancel()\">\r\n                <span class=\"icon-chevron-left-thin\"></span> Cancel\r\n            </button>\r\n        </div>\r\n        <div class=\"signature__clear\">\r\n            <button ng-click=\"clear()\" ng-disabled=\"!isDirty()\">\r\n                Clear\r\n            </button>\r\n        </div>\r\n        <div class=\"signature__submit\">\r\n            <button ng-click=\"submit()\" ng-disabled=\"!isDirty()\">\r\n                <span class=\"icon-check\"></span> Submit\r\n            </button>\r\n        </div>\r\n    </div>\r\n    <div class=\"signature__body\">\r\n        <div class=\"signature__label\">Please Sign Here</div>\r\n        <canvas class=\"signature__pad\"></canvas>\r\n    </div>\r\n</div>\r\n```"}}