Android emulator how to display image to remote destination in flask - python

I was referring to this github https://github.com/ahmedfgad/AndroidFlask and https://heartbeat.comet.ml/uploading-images-from-android-to-a-python-based-flask-server-691e4092a95e. I was unable to display the images into the remote destination from android emulator. I dont think the source code that they provide, do display images to the remote destination using flask.
Below is my github. It shows all the changes I have made.
https://github.com/2100723/AndroidEmulator/tree/main. I have made changes to the flask_server.py and images_template.html which is located in the templates folder . I need in the image to display in the remote host.
My android emulator has managed to save my images from emulator in the file call static whenever press connect to server & upload enter image description here. All I left is to send my image to a remote destination.
#Flask_server.py
import flask
import werkzeug
import time
app = flask.Flask(__name__, static_folder='static')
#app.route('/', methods = ['GET', 'POST'])
def handle_request():
image_paths = []
files_ids = list(flask.request.files)
print("\nNumber of Received Images : ", len(files_ids))
image_num = 1
for file_id in files_ids:
print("\nSaving Image ", str(image_num), "/", len(files_ids))
imagefile = flask.request.files[file_id]
filename = werkzeug.utils.secure_filename(imagefile.filename)
print("Image Filename : " + imagefile.filename)
timestr = time.strftime("%Y%m%d-%H%M%S")
file_path = timestr+'_'+filename
imagefile.save(file_path)
image_paths.append(filename)
image_num = image_num + 1
print("\n")
return flask.render_template('image_template.html', images=image_paths)
app.run(host="0.0.0.0", port=5000, debug=True)
#image_template.html
<!doctype html>
<html>
<head>
<title>Image Gallery</title>
</head>
<body>
<h1>Image Gallery</h1>
{% for image in images %}
<img src="{{ url_for('static', filename=image) }}" alt="image" width="200">
{% endfor %}
</body>
</html>
I try changing my Flask_server.py code and adding image_template.html to make my code to display to the remote server using flask. Nothing is display in the remote destination using flask

Related

Flask App | render template and start automatic download afterwards

I created a Flask app, which receives an input file, extracts the content, converts it to another format and returns a compressed file with the converted content.
#app.route('/', methods=['GET', "POST"])
#app.route('/home', methods=['GET', "POST"])
def home():
form = UploadFileForm()
file = form.file.data
if form.validate_on_submit():
file.save(os.path.join(os.path.abspath(os.path.dirname(__file__)), app.config['UPLOAD_FOLDER'], secure_filename(
file.filename)))
# 1. unzip files in directory
unzip(file.filename)
# 2. starts conversion process
conversion_status = converter().failed_files
# 3. compress generated DICOM files into export .zip file
zip_dir("static/results/conversion")
# 4. routes to downloading page with corresponding download action
return redirect(url_for('download'))
return render_template('index.html', form=form)
So far everything works. Currently I'm routing in step 4 to another function, which renders a result page, telling, if the conversion was fine. It also prints the export files and by clicking on them, the can be downloaded.
#app.route('/download')
def download():
return render_template('download.html', files=os.listdir('static/results/export'), status=conversion_status)
#app.route('/download/<filename>')
def download_file(filename):
return send_from_directory('static/results/export', filename)
Because I'm running that app on a azure web app url, I want to change the process into:
Rendering the result page
Downloading the content automatically afterwards, without user input
Like this:
return render_template('download.html', files=os.listdir('static/results/export'), status=conversion_status)
return send_from_directory('static/results/export', filename)
But I do not have any idea how to render two things after each other
It's not feasible to render two things consecutively within one endpoint.
However, there is a possibility to download the file automatically using JavaScript.
To find your current result within the list of files, you can pass the name as a parameter to the endpoint for the results.
return redirect(url_for('download', f=filename))
Within the endpoint, you ask for this parameter and pass it on to the template along with the list of files found. You can use a simple comparison to identify the file and use an attribute to mark the anchor for download as current.
#app.route('/download')
def download():
current = request.args.get('f')
files = os.listdir('static/results/export')
return render_template('download.html', **locals())
<ul>
{% for file in files -%}
<li>
<a
class="{{ ('', 'dwl-current')[current and current == file] }}"
href="{{ url_for('download_file', filename=file) }}"
download
>{{file}}</a></li>
{% endfor -%}
</ul>
If you add the anchor to run the download, it is now possible to click it automatically.
<script type="text/javascript">
(() => {
const elem = document.querySelector('a.dwl-current');
elem && elem.click();
})();
</script>

FastAPI serving static files through symlinks

I have mounted the static directory in my FastAPI app using the following code:
from fastapi.staticfiles import StaticFiles
app = FastAPI(
title="Title of the Application",
description="Over all description of the application")
app.mount("/public", StaticFiles(directory='public'), name='public')
If I have a symlink pointing to a path outside the app folder, e.g.
/home/xyz/app/main.py
/home/xyz/app/index.html
/home/xyz/app/public/data -> /home/xyz/static/whatever.tgz
The FastAPI application can recognize the URL xyz.com/public/index.html, but it can't recognize xyz.com/public/data.
Is this doable? Unfortunately, I cannot use FileResponse due to the blob size being too large. I want to return the file with a simple link somehow.
It is doable, as long as you mount a StaticFiles instance on that specific path as well. For example:
app.mount("/public", StaticFiles(directory="public"), name="public")
app.mount("/publicsym", StaticFiles(directory="public/data"), name="publicsym")
Then in your Jinja2 template you can requesst the files as below:
<link href="{{ url_for('public', path='/styles.css') }}" rel="stylesheet">
<img src="{{ url_for('publicsym', path='/image.png')}}" width="50%">
or, as per your given example (if there is a "static" directory including a "whatever.tgz" file):
{{ url_for('publicsym', path='static/whatever.tgz')}}

web cam in a webpage using flask and python

I have created a face recognition model using keras and tensorflow, and now I am trying to convert it as a web application using flask and python. My requirement is that, I need a live webcam displayed on the webpage and by clicking on a button it should take the picture and save it to a specified directory, and using that picture the application should recognize the person. if the person is not found in the dataset then a message should be displayed over the webpage that unknown identity is been found. To do this job I have started learning flask and after that when it comes to the requirement it was very difficult for me. somebody help me out to solve this situation.
What you want to do is streaming with Flask by using the webcam Stream and handle it with Machine Learning. Your main script for the web server in flask will allow you to load your index.html file and then Stream each frame through the /video_feed path:
from flask import Flask, render_template, Response, jsonify
from camera import VideoCamera
import cv2
app = Flask(__name__)
video_stream = VideoCamera()
#app.route('/')
def index():
return render_template('index.html')
def gen(camera):
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
#app.route('/video_feed')
def video_feed():
return Response(gen(video_stream),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='127.0.0.1', debug=True,port="5000")
Then you need the VideoCamera class in wich you will handle each frame and where you can make every prediction or processing you want on the frames. The camera.py file :
class VideoCamera(object):
def __init__(self):
self.video = cv2.VideoCapture(0)
def __del__(self):
self.video.release()
def get_frame(self):
ret, frame = self.video.read()
# DO WHAT YOU WANT WITH TENSORFLOW / KERAS AND OPENCV
ret, jpeg = cv2.imencode('.jpg', frame)
return jpeg.tobytes()
And finally the page showing the video Stream in the html file index.html (in the templates/ folder, if not exist generate it) :
<!DOCTYPE html>
<html lang="en">
<head>
<title>Video Stream</title>
</head>
<body>
<img src="{{ url_for('video_feed') }}" />
</body>
</html>
from flask import Flask,request,jsonify
import numpy as np
import cv2
import tensorflow as tf
import base64
app = Flask(__name__)
graph = tf.get_default_graph()
#app.route('/')
def hello_world():
return """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<video id="video" width="640" height="480" autoplay></video>
<button id="snap">Snap Photo</button>
<canvas id="canvas" width="640" height="480"></canvas>
</body>
<script>
var video = document.getElementById('video');
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true }).then(function(stream) {
//video.src = window.URL.createObjectURL(stream);
video.srcObject = stream;
video.play();
});
}
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var video = document.getElementById('video');
// Trigger photo take
document.getElementById("snap").addEventListener("click", function() {
context.drawImage(video, 0, 0, 640, 480);
var request = new XMLHttpRequest();
request.open('POST', '/submit?image=' + video.toString('base64'), true);
request.send();
});
</script>
</html>
"""
# HtmlVideoElement
#app.route('/test',methods=['GET'])
def test():
return "hello world!"
#app.route('/submit',methods=['POST'])
def submit():
image = request.args.get('image')
print(type(image))
return ""`
i have done like this, but the problem is that, when calling the API /submit in decorator, i get my image stored as HTMLVideoElement when print the type of image variable, I dont know how to convert it into Jpeg format and use it for further purpose.

Render default image in flask

I'm using url_for to generate my images url.
<img src="{{ url_for('static', filename='imgs/' + images[id]) }}" >
How to make url_for return /static/imgs/default.jpg when the requested image does not exist on the server ?
Solution 1: HTML / JavaScript
You can use onerror attribute:
<img src="{{ url_for('static', filename='imgs/' + images[id]) }}" onerror="this.src='/static/imgs/default.jpg'">
Or listen error event for img element with JavaScript (jQuery):
$('img').on("error", function() {
$(this).attr('src', '/static/imgs/default.jpg');
});
Solution 2: Flask
If you just want make it with Flask, you will need to create a custom view function to handle your images, for example (not test yet):
import os
from flask import send_from_directory
# ...
#app.route('/img/<path:filename>')
def get_image(filename):
static_path = os.path.join(app.root_path, 'static')
img_path = os.path.join(static_path, filename)
if not os.path.exists(img_path):
return send_from_directory(os.path.join(static_path, '/imgs/default.jpg'))
return send_from_directory(img_path)
Template code:
<img src="{{ url_for('get_image', filename='/static/imgs/' + images[id]) }}" >
Solution 3: Nginx
In production, you may use web server like Nginx to serve images, in this case, you can use [try_files](http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files) directive in Nginx:
location /static/imgs/ {
try_files $uri /static/imgs/default.jpg;
}

Insert image in python web.py

I have a file test1.py. I am using web.py to display it in a webpage.
import web
urls = ('/', 'hello','/bye', 'bye')
app = web.application(urls, globals(), True)
class hello:
def GET(self):
return """<html>
<head>
</head>
<body>
<img src="smile.png" alt="SAP Logo" width="500px" height="100px"/>
</body></html>"""
However, when run it will display:
127.0.0.1:59558 - - [28/Sep/2015 15:52:32] "HTTP/1.1 GET /" - 200 OK
127.0.0.1:59558 - - [28/Sep/2015 15:52:32] "HTTP/1.1 GET smile.png" - 404 Not Found
Image is placed in Desktop.
Create a "static" folder in your project root, copy your "smile.png" to that folder. Now change the src value of the img tag:
<img src="/static/smile.png" alt="SAP Logo" width="500px" height="100px"/>
You should see your smile.png in the brower now, for more info on serving static files in web.py, go visit "http://webpy.org/cookbook/staticfiles".

Categories