function bbox(ctx, cwidth, cheight, skip_width_calculation, skip_height_calculation) {
        if (typeof skip_width_calculation != 'boolean') skip_width_calculation = false;
        if (typeof skip_height_calculation != 'boolean') skip_height_calculation = false;
        if (skip_width_calculation && skip_height_calculation) throw "bbox: can't skip calculation of both width and height";
        var data = ctx.getImageData(0, 0, cwidth, cheight).data;
        var r = 0, c = 0;// r: row, c: column
        var top_line = -1, bottom_line = -1, left_line = -1, right_line = -1;
        var box_width = 0, box_height = 0;
        if (!skip_height_calculation) {
          // Find the top-most line with a non-white pixel
          for (r = 0; r < cheight; r++) {
            for (c = 0; c < cwidth; c++) {
              if (data[r * cwidth * 4 + c * 4 + 3]) {
                top_line = r;
                break;
              }
            }
            if (top_line != -1) break;
          }
          
          //find the last line with a non-white pixel
          if (top_line != -1) {
            for (r = cheight-1; r >= top_line; r--) {
              for(c = 0; c < cwidth; c++) {
                if(data[r * cwidth * 4 + c * 4 + 3]) {
                  bottom_line = r;
                  break;
                }
              }
              if (bottom_line != -1) break;
            }
            box_height = bottom_line - top_line + 1;
          }
        }

        if (!skip_width_calculation) {
          // Find the left-most line with a non-white pixel
          for (c = 0; c < cwidth; c++) {
            for (r = 0; r < cheight; r++) {
              if (data[r * cwidth * 4 + c * 4 + 3]) {
                left_line = c;
                break;
              }
            }
            if (left_line != -1) break;
          }

          //find the right most line with a non-white pixel
          if (left_line != -1) {
            for (c = cwidth-1; c >= left_line; c--) {
              for(r = 0; r < cheight; r++) {
                if(data[r * cwidth * 4 + c * 4 + 3]) {
                  right_line = c;
                  break;
                }
              }
              if (right_line != -1) break;
            }
            box_width = right_line - left_line + 1;
          }
        }
        //return the bounds
        if (!skip_height_calculation && !skip_width_calculation) {
          return {top: top_line, bottom: bottom_line, left: left_line, right: right_line, width: box_width, height: box_height};
        } else if (!skip_height_calculation) {
          return {top: top_line, bottom: bottom_line, height: box_height};
        } else {
          return {left: left_line, right: right_line, width: box_width};
        }
      }
/*
       * Calculates a tight bounding box on the contents of a canvas
       */
Calculates a tight bounding box on the contents of a canvas
Calculates a tight bounding box on the contents of a canvas
function bbox(ctx, cwidth, cheight, skip_width_calculation, skip_height_calculation) {
        if (typeof skip_width_calculation != 'boolean') skip_width_calculation = false;
        if (typeof skip_height_calculation != 'boolean') skip_height_calculation = false;
        if (skip_width_calculation && skip_height_calculation) throw "bbox: can't skip calculation of both width and height";
        var data = ctx.getImageData(0, 0, cwidth, cheight).data;
        var r = 0, c = 0;
        var top_line = -1, bottom_line = -1, left_line = -1, right_line = -1;
        var box_width = 0, box_height = 0;
        if (!skip_height_calculation) {
          for (r = 0; r < cheight; r++) {
            for (c = 0; c < cwidth; c++) {
              if (data[r * cwidth * 4 + c * 4 + 3]) {
                top_line = r;
                break;
              }
            }
            if (top_line != -1) break;
          }
          if (top_line != -1) {
            for (r = cheight-1; r >= top_line; r--) {
              for(c = 0; c < cwidth; c++) {
                if(data[r * cwidth * 4 + c * 4 + 3]) {
                  bottom_line = r;
                  break;
                }
              }
              if (bottom_line != -1) break;
            }
            box_height = bottom_line - top_line + 1;
          }
        }
        if (!skip_width_calculation) {
          for (c = 0; c < cwidth; c++) {
            for (r = 0; r < cheight; r++) {
              if (data[r * cwidth * 4 + c * 4 + 3]) {
                left_line = c;
                break;
              }
            }
            if (left_line != -1) break;
          }
          if (left_line != -1) {
            for (c = cwidth-1; c >= left_line; c--) {
              for(r = 0; r < cheight; r++) {
                if(data[r * cwidth * 4 + c * 4 + 3]) {
                  right_line = c;
                  break;
                }
              }
              if (right_line != -1) break;
            }
            box_width = right_line - left_line + 1;
          }
        }
        if (!skip_height_calculation && !skip_width_calculation) {
          return {top: top_line, bottom: bottom_line, left: left_line, right: right_line, width: box_width, height: box_height};
        } else if (!skip_height_calculation) {
          return {top: top_line, bottom: bottom_line, height: box_height};
        } else {
          return {left: left_line, right: right_line, width: box_width};
        }
      }
function bbox ( ctx , cwidth , cheight , skip_width_calculation , skip_height_calculation ) { if ( typeof skip_width_calculation != 'boolean' ) skip_width_calculation = false ; if ( typeof skip_height_calculation != 'boolean' ) skip_height_calculation = false ; if ( skip_width_calculation && skip_height_calculation ) throw "bbox: can't skip calculation of both width and height" ; var data = ctx . getImageData ( 0 , 0 , cwidth , cheight ) . data ; var r = 0 , c = 0 ; var top_line = - 1 , bottom_line = - 1 , left_line = - 1 , right_line = - 1 ; var box_width = 0 , box_height = 0 ; if ( ! skip_height_calculation ) { for ( r = 0 ; r < cheight ; r ++ ) { for ( c = 0 ; c < cwidth ; c ++ ) { if ( data [ r * cwidth * 4 + c * 4 + 3 ] ) { top_line = r ; break ; } } if ( top_line != - 1 ) break ; } if ( top_line != - 1 ) { for ( r = cheight - 1 ; r >= top_line ; r -- ) { for ( c = 0 ; c < cwidth ; c ++ ) { if ( data [ r * cwidth * 4 + c * 4 + 3 ] ) { bottom_line = r ; break ; } } if ( bottom_line != - 1 ) break ; } box_height = bottom_line - top_line + 1 ; } } if ( ! skip_width_calculation ) { for ( c = 0 ; c < cwidth ; c ++ ) { for ( r = 0 ; r < cheight ; r ++ ) { if ( data [ r * cwidth * 4 + c * 4 + 3 ] ) { left_line = c ; break ; } } if ( left_line != - 1 ) break ; } if ( left_line != - 1 ) { for ( c = cwidth - 1 ; c >= left_line ; c -- ) { for ( r = 0 ; r < cheight ; r ++ ) { if ( data [ r * cwidth * 4 + c * 4 + 3 ] ) { right_line = c ; break ; } } if ( right_line != - 1 ) break ; } box_width = right_line - left_line + 1 ; } } if ( ! skip_height_calculation && ! skip_width_calculation ) { return { top : top_line , bottom : bottom_line , left : left_line , right : right_line , width : box_width , height : box_height } ; } else if ( ! skip_height_calculation ) { return { top : top_line , bottom : bottom_line , height : box_height } ; } else { return { left : left_line , right : right_line , width : box_width } ; } }
Calculates a tight bounding box on the contents of a canvas
Calculates a tight bounding box on the contents of a canvas
// r: row, c: column // Find the top-most line with a non-white pixel //find the last line with a non-white pixel // Find the left-most line with a non-white pixel //find the right most line with a non-white pixel //return the bounds