Получите png файл через ajax и рисуйте на холсте с flask сервером - PullRequest
0 голосов
/ 24 апреля 2020

Как извлечь полученные данные png из ajax вызова и вставить в холст?

Видеофайл (mp4) загружается через ajax на flask сервер. Первый кадр извлекается с помощью Cv2, сохраняется и файл возвращается клиенту.

Я могу получить данные PNG в виде строки, но хочу отобразить изображение на холсте.

Я не могу ввести код, используя image.sr c = "data: image / PNG; base64" + data. Не уверены источник ошибки.

РЕДАКТИРОВАТЬ Я могу передать данные изображения в элемент img, он показывает только значок, а не само изображение.

flask функции - Функция main

@app.route('/',methods=['GET','POST'])
def request_from_main():
    if request.method == 'POST' and 'file' in request.files:
       file_object = request.files['file']
       secure_file_object = secure_filename(file_object.filename)
       file_object.save(f"uploads/{secure_file_object}")

       video_container = video_processing.process_saved_video_file(f"uploads/{secure_file_object}")

       saved_image_file_path,saved_image_file_name = video_container.save_image()
       return send_file(saved_image_file_path,mimetype='image/png',as_attachment=True)

       #return video_container.base_64_encode()
   elif request.method == 'GET':
       return render_template('index.html')
   else:
       return None

flask - cv2 сохраняет и предоставляет путь к файлу

    def save_image(self): # TODO add error checking for image
    cv2.imwrite(f"{self.file_structure}/{self.base_file_name}.png",self.current_image)
    return f"{self.file_structure}/{self.base_file_name}.png", f"{self.base_file_name}.png"

Клиент - JavaScript

<!-- language: lang-js -->
// Upload class
var Upload = function (file) {
    this.file = file;
};
Upload.prototype.getName = function() {
    return this.file.name;
};
Upload.prototype.doUpload = function () {
    var that = this;
    var formData = new FormData();

    // add assoc key values, this will be posts values
    formData.append("file", this.file, this.getName());
    formData.append("upload_file", true);

    // Change url according to flask design
    $.ajax({
        type: "POST",
        url: "/", 
        xhr: function () {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                myXhr.upload.addEventListener('progress', that.progressHandling, false);
            }
            return myXhr;
        },
        success: function (data) {

            console.log("SUCCESS, pushing to canvas");
            console.log(typeof data);
            $("#temp_storage_image").attr("src",data);
        },
        error: function (error) {
            console.log("ERROR")
            console.log(error);
        },
        async: true,
        data: formData, // What to send
        cache: false,
        contentType: 'image/png',
        //processData: false,
        dataType: 'image/png', // What to expect back from the server, must match otherwise error is thrown,
        timeout: 100000
    });
};

//Change id to your id
$("#file_upload_input").on("change", function (e) {
    var file = $(this)[0].files[0];
    console.log("Made it here, to on change file upload");
    var upload = new Upload(file);
    console.log("Made it past new Upload");
    // maby check size or type here with upload.getSize() and upload.getType()

    // execute upload
    upload.doUpload();
});

Клиент - HTML

<body>
  <div class="container">
    <div id="project_structure_menu">

      <form id="file_upload" idmethod="POST" enctype="multipart/form-data" action="{{url_for('request_from_main')}}"> <!-- request_from_main is flask function -->
        <div class="input-field col-sm">
          <input id="file_upload_input" type="file" name="file">
        </div>
        <div class="input-field col-sm">
          <button id="file_upload_submit_button" type="submit">Submit</button>
      </div>
      </form>

      <div id="progress-wrp" class="col s2">
        <div class="progress-bar"></div>
        <div class="status">0%</div>
      </div>

    </div>


    <div id="labeling_ui" class="row">
     <img id="temp_storage_image"></img>
     <canvas id="main_drawing" width="100" height="100" style="border:1px solid #d3d3d3;"></canvas>
    </div>
  </div>  

  <!-- TODO Make own file: Get form data and send it to server -->
  <script type="text/javascript" src="{{url_for('static',filename='scripts/file_upload.js')}}"></script> <!-- AJAX file upload -->
</body>

1 Ответ

0 голосов
/ 25 апреля 2020

Решено! Мой закон.

Как отправить видеофайл через ajax, обработать видео и вернуть первый кадр в теге img

  1. GET запрос на получение индекса. html,. js,. css et c
  2. AJAX для отправки видеофайла на сервер Flask через POST-запрос
  3. Flask для обработки видеофайла с помощью cv2 и сохранения образ. Возврат изображения через send_file.
  4. Вставьте тег img в "#hiddendiv", укажите sr c, чтобы собрать изображение с помощью запроса GET.
  5. Использовать canvas.getContext ('2d) .drawImage (...)

Это решение отправляет строку идентификатора для сбора файла через запрос get. Вы не уверены, насколько безопасно это решение.

Flask Код

@app.route('/',methods=['GET','POST'])
def request_from_main():
    if request.method == 'POST' and 'file' in request.files:
    file_object = request.files['file']
    secure_file_object = secure_filename(file_object.filename)
    file_object.save(f"uploads/{secure_file_object}")

    video_container = video_processing.process_saved_video_file(f"uploads/{secure_file_object}")

        saved_image_file_path,saved_image_file_name = video_container.save_image()
        return  send_file(saved_image_file_path)
    elif request.method == 'GET':
        return render_template('index.html')
    else:
        return None
# What the identifier string is passed to and retrieve the image to send with send_file
@app.route('/processed_images',methods=['GET'])
def new_data_request():
    if request.method == 'GET':
        temp = request.args
        file_name = request.args.get('file')
        return send_file(f"{os.getcwd()}/uploads/{file_name}")

Обработка видео

class video_file_container():
    '''
        Stores the video path in memory so that it can be retrieved and images served to client
    '''
    file_structure = f"{os.getcwd()}/uploads"
    def __init__(self,video_file_path:str,video_capture:cv2.VideoCapture,first_image):             # TODO add error checking for  
        if type(video_file_path) != str:
            raise TypeError(f"ERROR[video_file_container.__init__]: video_file_path is not of type str instead it is {type(video_file_path)}")
        if os.path.exists(video_file_path) == False:
            raise ValueError(f"ERROR[video_file_container.__init__]: video_file_path=|{video_file_path}| does not exist")
        if type(video_capture) != cv2.VideoCapture:
            raise TypeError(f"ERROR[video_file_meta_data.__init__]: video_capture is not of type cv2.VideoCapture instead it is {type(video_capture)}")

        self.location = video_file_path
        self.video_file_name = os.path.basename(video_file_path)
        self.base_file_name = os.path.splitext(self.video_file_name)[0]
        self.number_of_frames = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))
        self.frame_width = int(video_capture.get(cv2.CAP_PROP_FRAME_WIDTH))
        self.frame_height = int(video_capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
        self.video_fps  = video_capture.get(cv2.CAP_PROP_FPS)
        self.current_frame = 0
        self.current_image = first_image

    def save_image(self): # TODO add error checking for image
        successful_write = cv2.imwrite(f"{self.file_structure}/{self.base_file_name}.png",self.current_image)
        if successful_write is True:
            return f"processed_images/{self.base_file_name}.png", f"{self.base_file_name}.png"
        return None

JavaScript - AJAX - jQuery

Индекс - HTML

<div class="container">
<div id="project_structure_menu">

  <form id="file_upload" idmethod="POST" enctype="multipart/form-data" action="{{url_for('request_from_main')}}"> <!-- request_from_main is flask function -->
    <div class="input-field col-sm">
      <input id="file_upload_input" type="file" name="file">
    </div>
    <div class="input-field col-sm">
      <button id="file_upload_submit_button" type="submit">Submit</button>
  </div>
  </form>

  <div id="progress-wrp" class="col s2">
    <div class="progress-bar"></div>
    <div class="status">0%</div>
  </div>

</div>


<div id="labeling_ui" class="row">
  <canvas id="main_drawing" width="1920" height="1080" style="border:1px solid #d3d3d3;"></canvas>
</div>
<div id="hidendiv"></div>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...