Pass cropperjs output to OCR in Django

Viewed 148

In my Django App someone uploads an image, makes a box selection, clicks the button crop and the image inside the box is cropped using fengyuachen Cropperjs. I want to pass the cropped image to an OCR (in my case I use Pytesseract. I had two independent apps (one for cropping and one for OCR and both works. Now, I want to join them). So, my questions is :

How can I pass the cropped Image to the form input that is used by pytesseract to extract the information? I'm new to Javascript so I've been struggling with it.

I think these images could help. Someone uploads and image, selects the cropping box and then select the button crop. The image is displayed

"Someone" would click on the button Send to OCR and then Django Views recieves the input

HTML and JS code

<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.11/cropper.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.11/cropper.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

</head>
<body>
    
  <h1>Upload Image to Crop</h1>
  <input type="file" name="image" id="image" enctype="multipart/form-data" multiple="true" onchange="readURL(this);" />
  <div class="image_container">
      <img id="blah" src="#" alt="your image" height="600px" width="600px" />
  </div>
  
  <!--<div id="cropped_result" ></div>-->
  <button id="crop_button">Crop</button> 

{% if ....%} <!-- I am getting multivalue key error, there has to be and if statement here I think)
<!-- Cropped image passes to the OCR-->

<form method="post" enctype="multipart/form-data"  >
  {% csrf_token %}  
<input type="submit" value="Send to OCR" name="cropped_result" >
<div class="row">
<div id="cropped_result" >
</div>
</form>
<p><textarea name="dataPath" >{{k}}</textarea></p>
{% endif %}
  <script type="text/javascript" defer>
    function readURL(input) {
        if (input.files && input.files[0]) {
            var reader = new FileReader();
            reader.onload = function (e) {
                $('#blah').attr('src', e.target.result)
            };
            reader.readAsDataURL(input.files[0]);
            setTimeout(initCropper, 1000);
        }
    }
    function initCropper(){
        var image = document.getElementById('blah');
        var cropper = new Cropper(image, {
          aspectRatio: NaN,
          crop: function(e) {
            console.log(e.detail.x);
            console.log(e.detail.y);
          }
        });

        // On crop button clicked
        document.getElementById('crop_button').addEventListener('click', function(){
            var imgurl =  cropper.getCroppedCanvas().toDataURL();
            var img = document.createElement("img");
            img.src = imgurl;
            document.getElementById("cropped_result").appendChild(img);


        })
    }
</script>

</body>

</html>

Django View used for the OCR

from django.shortcuts import render
from django.core.files.storage import FileSystemStorage
from PIL import Image
import pytesseract
import os
import csv

 def predictImage(request):

    fileObj = request.FILES['cropped_result']
    fs = FileSystemStorage()
    filePathName=fs.save(fileObj.name , fileObj)
    filePathName=fs.url(filePathName)
    testimage = '.'+filePathName
    k=pytesseract.image_to_string(Image.open(testimage))
    context = {'filePathName':filePathName,'k':k}
    return render(request,'crop.html',context)

Thanks!

1 Answers

Post request is sent using Ajax. Then the view is quite straightforward. No need to use base64, blob or any binary representation of the image. (Maybe I'm missing something or Django is really user friendly). Anyway, I hope this could help someone.

from PIL import Image
import pytesseract
import os


def main_view(request):
    
    form = ImageForm(request.POST or None ,request.FILES or None)
    if form.is_valid():
        instance = form.save()
        path = instance.file
        text = pytesseract.image_to_string(Image.open(path))
        print(text)
        
    context = {'form':form}
    return render(request, 'main.html',context)
Related