angularjs - Rgba to basic matrix (0 for white pixel, 1 for anything else) transformation with BufferedImage -


i'm working on optical character recognition school project.

at step, have draw character apply freeman chain code it.

i'm drawing on canvas using sketch.js

front end code handled angularjs, end spring & bufferedimage

based on 2 tutorials :

for canvas drawing : https://developer.mozilla.org/en-us/docs/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas#grayscaling_and_inverting_colors

for sketch.js : https://intridea.github.io/sketch.js/docs/sketch.html

i wrote client code :

...     <div class="container">         <div ng-controller="ctrl">             <canvas ng-model="canvas" ng-click="enablesave()" class="panel panel-default" width="200" height="200"></canvas>             <form class="form-horizontal" enctype="multipart/form-data">                 <div class="input-group col-md-4">                     <span class="input-group-btn">                         <button ng-click="clear()" id="clear" type="button" class="btn btn-default">clear</button>                     </span>                     <input ng-model="num" type="number" id="num" class="form-control" type="text">                     <span class="input-group-btn">                         <button ng-click="save()" ng-disabled="modif == false" type="button" class="btn btn-success">save</button>                     </span>                 </div>             </form>         </div>     </div>     <script type="text/javascript" src="assets/js/jquery-2.2.0.min.js"></script>     <script type="text/javascript" src="assets/js/sketch.min.js"></script>     <script type="text/javascript" src="assets/js/angular.min.js"></script>     <script type="text/javascript">         var app = angular.module('app', []);         app.controller('ctrl', ['$scope', '$log', '$http', function($scope, $log, $http) {             // init             $scope.modif = false;             $scope.canvas = angular.element('canvas');             $scope.context = $scope.canvas[0].getcontext('2d');             $scope.canvas.sketch({                 defaultcolor: "#000000",                 defaultsize: 2             });              // enable save button if user draw on canvas             $scope.enablesave = function() {                 $scope.modif = true;             };             // convert image blob : https://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata             $scope.toblob = function(datauri) {                 var bytestring;                 if (datauri.split(',')[0].indexof('base64') >= 0)                     bytestring = atob(datauri.split(',')[1]);                 else                     bytestring = unescape(datauri.split(',')[1]);                 var mimestring = datauri.split(',')[0].split(':')[1].split(';')[0];                 var ia = new uint8array(bytestring.length);                 (var = 0; < bytestring.length; i++)                     ia[i] = bytestring.charcodeat(i);                 return new blob([ia], {                     type: mimestring                 });             };             // send user's input server             $scope.save = function() {                 var img = $scope.canvas[0].todataurl('image/png');                 $log.info(img);                 var fd = new formdata();                 var blob = $scope.toblob(img);                 fd.append('img', blob);                 $http.post('add.html', fd, {                         withcredentials: true,                         headers: {                             'content-type': undefined                         },                         transformrequest: angular.identity                     })                     .success(function(result) {                         $log.info(result);                     })                     .error(function(data, status) {});                 // clear canvas                 img = null;                 $scope.clear();                 // disable save button                 $scope.modif = false;             };             // clear canvas             $scope.clear = function() {                 $scope.context.clearrect(0, 0, $scope.canvas[0].width, $scope.canvas[0].height);                 $scope.canvas.sketch('actions', []);             }         }]);         $(document).ready(function() {});     </script> </body>  </html> 

spring controller :

@requestmapping(value = "/add", method = requestmethod.post) @responsebody public string add(@requestparam("img") multipartfile image) throws ioexception {     log.info("add : post");      log.info("bytes image : " + image.getbytes().length);      bufferedimage original = imageio.read(image.getinputstream());     bufferedimage non_transparent = new bufferedimage(original.getwidth(), original.getheight(),             bufferedimage.type_int_rgb);     bufferedimage black_white = new bufferedimage(non_transparent.getwidth(), non_transparent.getheight(),             bufferedimage.type_byte_binary);      non_transparent.getgraphics().drawimage(original, 0, 0, null);     non_transparent.getgraphics().dispose();      black_white.getgraphics().drawimage(non_transparent, 0, 0, null);     black_white.getgraphics().dispose();      byte[] original_pixels = ((databufferbyte) original.getraster().getdatabuffer()).getdata();     log.info("original pixels : " + original_pixels.length);      int[] non_transparent_pixels = ((databufferint) non_transparent.getraster().getdatabuffer()).getdata();     log.info("non transparent pixels : " + non_transparent_pixels.length);      byte[] black_white_pixels = ((databufferbyte) black_white.getraster().getdatabuffer()).getdata();     log.info("black white pixels : " + black_white_pixels.length);      fileoutputstream fos_original = new fileoutputstream("original.txt");     fos_original.write(original_pixels);     fos_original.close();     file f_original = new file("original.png");     imageio.write(original, "png", f_original);      file f_non_transparent = new file("non_transparent.png");     imageio.write(non_transparent, "png", f_non_transparent);      fileoutputstream fos_black_white = new fileoutputstream("black_white.txt");     fos_black_white.write(black_white_pixels);     fos_black_white.close();     file f_black_white = new file("black_white.png");     imageio.write(black_white, "png", f_black_white);     return status; } 

whatever picture format choose in var img = $scope.canvas[0].todataurl('image/png'); the picture sent transparent except drawn on pixels.

i want transform sent picture rgba basic (0 white pixel, 1 else) matrix.

i started testing bufferedimage class transformation, because i've read creating new bufferedimage image type of type_byte_binary original bufferedimage

but method produces totally black image bytes set 0.

so have 2 question ? there way prevent transparency on canvas ? & there built in way rgba 0/1 matrix transformation ?

thanks.

for question 1 :

is there way prevent transparency on canvas ?

there several actually.

  • you can pass {alpha: false} object canvas.getcontext('2d') method.
    disable default transparency of context, setting black rectangle. note won't disable transparency of further drawn objects (ctx.globalalpha , rgba colors still honored, calculated on black background). because default, transparency on canvas rgba(0,0,0,0), removing alpha value leave rgb(0,0,0).

  • an other solution, fill rectangle, act background, in solid color want.

var img = new image();  img.onload = function(){      //_____option 1______//      // #noalpha canvas' 2d context, alpha parameter set false    var nactx = noalpha.getcontext('2d', {alpha:false});    // can draw partially transparent image , have black background    nactx.drawimage(img, 20,20);            //_____option 2______//          // #whitefill canvas' 2d context    var wfctx = whitefill.getcontext('2d');    // set context' fill color white    // can css color argument    wfctx.fillstyle = 'white';    // fill rectangle big canvas    wfctx.fillrect(0,0, whitefill.width, whitefill.height);    // you've got white background    // can draw partially transparent image , have white background    wfctx.drawimage(img, 20,20);    };  img.src = "https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png"
body{background-color: ivory;}
<canvas id="noalpha" width="70" height="70"></canvas>  <canvas id="whitefill" width="70" height="70"></canvas>

for second question,

is there built in way rgba 0/1 matrix transformation ?

no, or @ least, not in knowledge.

what : keep transparency of images, except if need consider white transparent, in case, see last snippet of answer.

then it's quite easy use ctx.getimagedata() method, loop through data property , check alpha values. (getimagedata.data typedarray representing rgba values of requested part of canvas (red, green, blue , alpha channels)).

var img = new image();    // able use getimagedata method, have sure don't taint canvas  // see http://stackoverflow.com/questions/34743987/canvas-image-crossplatform-insecure-error/34755162#34755162 more info  img.crossorigin = 'anonymous';    img.onload = function(){      var ctx = source.getcontext('2d');    // draw image , keep transparency    ctx.drawimage(img, 0,0);        var yourarray = [];    // canvas' imagedata position 0,0 , of ful size of canvas    var imagedata = ctx.getimagedata(0,0, source.width, source.height);    // rgba array of imagedata    var data = imagedata.data;    // loop through pixels, checking alpha value    for(var i=3; i<data.length-3; i+=4){      // non-transparent pixel      if(data[i] > 0) {        yourarray.push(1);        // set r,g,b values 0 (black)        data[i-3] = data[i-2] = data[i-1] = 0;        // set alpha value 255        data[i] = 255;        }      else{        yourarray.push(0);        }      }    console.log(yourarray);    // draw new image on export canvas (could alos first 1    output.getcontext('2d').putimagedata(imagedata, 0,0);    };  img.src = "https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png"
body{background-color: ivory;}
<canvas id="source" width="32" height="32"></canvas>  <canvas id="output" width="32" height="32"></canvas>

here how loop through pixels values if need see white ones transparent :

var img = new image();  img.crossorigin = 'anonymous';    img.onload = function(){      var ctx = source.getcontext('2d');      ctx.drawimage(img, 0,0);        var imagedata = ctx.getimagedata(0,0, source.width, source.height);    var data = imagedata.data;        var yourarray = [];        // loop through pixels, checking every rgba value    for(var i=0; i<data.length; i+=4){      // non-white pixel      if( data[i]+data[i+1]+data[i+2]+data[i+3] < 255*4 ) {        yourarray.push(1);        // set r,g,b values 0 (black)        data[i] = data[i+1] = data[i+2] = 0;        // set alpha value 255        data[i+3] = 255;       }else{        yourarray.push(0);        // set alpha value 0        data[i+3] = 0;       }      }    console.log(yourarray);    output.getcontext('2d').putimagedata(imagedata, 0,0);    };  // image white background  img.src = "https://dl.dropboxusercontent.com/s/iac97oiynwthrg5/somewhite.png"
body{background-color: ivory;}
<canvas id="source" width="284" height="383"></canvas>  <canvas id="output" width="284" height="383"></canvas>


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -