JCrop User Selected Image

1.4k views Asked by At

I have been able to use JCrop example code to both select an area on an image, show a preview of the selected area, and get the coordinates of the selected area.

But I am only able to do this for a pre-loaded image. I would like a user to select an image from his file system, bring it up to the browser, and then allow him/her to do the above.

I tried to substitute the hard-coded reference to the image with a simple Javascript function. On its own, the Javascript code does work to simply allow a user to select an image and show that image in the browser.

But when placed in the JQuery/JCrop code that I am using for selecting an area of the image to preview, it does not seem to work.

Here is the full code as it is right now:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Aspect Ratio with Preview Pane | Jcrop Demo</title>
  <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />

<script src="../js/jquery.min.js"></script>
<script src="../js/jquery.Jcrop.js"></script>
<script type="text/javascript">
  jQuery(function($){

    // Create variables (in this scope) to hold the API and image size
    var jcrop_api,
        boundx,
        boundy,

        // Grab some information about the preview pane
        $preview = $('#preview-pane'),
        $pcnt = $('#preview-pane .preview-container'),
        $pimg = $('#preview-pane .preview-container img'),

        xsize = $pcnt.width(),
        ysize = $pcnt.height();

    console.log('init',[xsize,ysize]);
    $('#target').Jcrop({
      onChange: updatePreview,
      onSelect: updatePreview,
      aspectRatio: xsize / ysize
    },function(){
      // Use the API to get the real image size
      var bounds = this.getBounds();
      boundx = bounds[0];
      boundy = bounds[1];
      // Store the API in the jcrop_api variable
      jcrop_api = this;

      // Move the preview into the jcrop container for css positioning
      $preview.appendTo(jcrop_api.ui.holder);
    });

    function updatePreview(c)
    {
      if (parseInt(c.w) > 0)
      {
        var rx = xsize / c.w;
        var ry = ysize / c.h;

        $pimg.css({
          width: Math.round(rx * boundx) + 'px',
          height: Math.round(ry * boundy) + 'px',
          marginLeft: '-' + Math.round(rx * c.x) + 'px',
          marginTop: '-' + Math.round(ry * c.y) + 'px' 
        });
      }

      $('#x1').val(c.x);
      $('#y1').val(c.y);
      $('#x2').val(c.x2);
      $('#y2').val(c.y2);
      $('#w').val(c.w);
      $('#h').val(c.h);
    };

  });
</script>

<link rel="stylesheet" href="demo_files/main.css" type="text/css" />
<link rel="stylesheet" href="demo_files/demos.css" type="text/css" />
<link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
<style type="text/css">

/* Apply these styles only when #preview-pane has
   been placed within the Jcrop widget */
.jcrop-holder #preview-pane {
  display: block;
  position: absolute;
  z-index: 2000;
  top: 75px;
  right: -270px;
  padding: 6px;
  border: 1px rgba(0,0,0,.4) solid;
  background-color: white;

  -webkit-border-radius: 6px;
  -moz-border-radius: 6px;
  border-radius: 6px;

  -webkit-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
  box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);
}

/* The Javascript code will set the aspect ratio of the crop
   area based on the size of the thumbnail preview,
   specified here */
#preview-pane .preview-container {
  width: 170px;
  height: 170px;
  overflow: hidden;
}

</style>

</head>
<body>

<div class="container">
<div class="row">
<div class="span12">
<div class="jc-demo-box">

<div class="page-header">
<h1>Aspect Ratio with Preview Pane</h1>
</div>

  <input type = "file"  id = "src" />
  <img id="target" alt="[Jcrop Example]" />

  <div id="preview-pane">
    <div class="preview-container">
      <img id="target_preview" class="jcrop-preview" alt="Preview" />
    </div>
  </div>

  <script>
    function showImage(src,target,target_preview) {
            var fr=new FileReader();
            // when image is loaded, set the src of the image where you want to display it
            fr.onload = function(e) { 
                   target.src = this.result;
                   target_preview.src = this.result 
            };
            src.addEventListener("change",function() {
                // fill fr with image data    
                fr.readAsDataURL(src.files[0]);
            });
    }

    var src = document.getElementById("src");
    var target = document.getElementById("target");
    var target_preview = document.getElementById("target_preview");
    showImage(src,target,target_preview);

  </script> 

  <!-- This is the form that our event handler fills -->
  <form id="coords"
    class="coords"
    onsubmit="return false;"
    action="http://example.com/post.php">

    <div class="inline-labels">
    <label style="display: none">X1 <input type="text" size="4" id="x1" name="x1"/></label>
    <label style="display: none">Y1 <input type="text" size="4" id="y1" name="y1"/></label>
    <label style="display: none">X2 <input type="text" size="4" id="x2" name="x2"/></label>
    <label style="display: none">Y2 <input type="text" size="4" id="y2" name="y2"/></label>
    <label style="display: none">W <input type="text" size="4" id="w" name="w"/></label>
    <label style="display: none">H <input type="text" size="4" id="h" name="h"/></label>
    </div>
  </form>



<div class="clearfix"></div>

</div>
</div>
</div>
</div>

</body>
</html>

The Javascript relevant to this task is embedded within the tags.

Here's an SO post that I think tried to address the same thing, but I just didn't understand at all: Input file show live selected image in JCrop

I have heard of a JCrop function called "setImage" which can be used for this purpose. Does anyone know exactly how to use it?

Please let me know if you need any other information. Thank you.

1

There are 1 answers

2
FancyPants On

I would suggest you to populate the db with images, on load get those images, make an array list of objects. Convert those imigase into StreamedContent from the byte[] you got from the db. And place them in a primeface data table.