Flask Image Upload Generating a Border - python

I'm uploading image in Flask and after uploading the image is getting a black border. I'm using the image further in Processing and after processing the border is visible in white color, I tried the same Image processing code on a image taken directly from folder and not uploaded through flask and it working correctly and no borders are formed. Can Someone please suggest what to do ?
Here is my code of flask to upload file, form type is multipart form :
#app.route('/success', methods = ['POST'])
def success():
if request.method == 'POST':
f = request.files['file']
f.save(f.filename)
... next logic

Related

Object Detection Flask App cuasing image overwrites in consecutive requests

I'm trying to implement an object detection web app using flask.
The flow of my app is:
The user will upload an image.
The image will get saved to a directory ('/static/uploads' folder)
A function called 'get_images' will read the image, load the object detector model, and finally write the image with detection at the specified folder ('/static/detections/')
A template called 'uploaded.html' will then display the uploaded image from the upload directory, and also the image with detections from detections directory.
The app runs fine when ran for the first time and when the server is launched again. But if I try to upload another image after running detection on the first image, the image with detections get overwritten with the previous image but its name is preserved, ultimately resulting in the first image with detections being displayed again and again. My flask app (app.py) code is as follows:
app = Flask(__name__)
UPLOAD_FOLDER = './static/uploads/'
DETECTION_FOLDER = './static/detections/'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['DETECTION_FOLDER'] = DETECTION_FOLDER
# app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
# app.config['TEMPLATES_AUTO_RELOAD'] = True
#app.route("/")
def index():
return render_template("index.html")
#app.route("/about")
def about():
return render_template("about.html")
#app.route('/uploader', methods = ['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
# create a secure filename
filename = secure_filename(f.filename)
print(filename)
# save file to /static/uploads
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
print(filepath)
f.save(filepath)
print(filepath)
get_image(filepath,filename)
return render_template("uploaded.html", display_detection = filename, fname = filename)
if __name__ == '__main__':
app.run(port=4000, debug=True)
Function get_image() is a method of file app_helper.py and is ultimately performing a cv2.imwrite on the image with detections. I thought the problem might be with this section of the code as this is the only place where any 'writing' is done. So, I ran the app_helper.py function multiple times, and not once the images were overwritten (in the '/static/detections/' folder).
I'm including some images to explain my concern better,
Page after running the first detection looks like this
'/static/detections/' folder after first run
'/static/uploads/' folder after uploading my 2nd image
As soon I run the detector, this is what happens in the '/static/detections/' folder, though the file name is preserved
And since the new file name (phone.jpg) is now associated with same image as 'phone2.jpg' the detection image doesn't not change. I kept repeating this, and any new image I uploaded - it got overwritten by 'phone2.jpg'!
I repeat, I tried running get_images() method separately - even after running it on multiple images NO SUCH OVERWRITES took place. For ref, get_images() method is a slight modification of this code. ('Uploaded.html' relies on the filename to display images, which is being maintained here)
e.g. get_images('/data/images/kite.jpg','kite.jpg')
ps- I also tried adding,
# app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
# app.config['TEMPLATES_AUTO_RELOAD'] = True
also, after the first execution, I emptied the uploads and detections folder to check if that helps,
But these didn't work.
Kindly help me out, I want my app to bear multiple runs (of upload and detect) without such issues.
Thank you.

how can I open an image of FileStorage type in Pillow

in my flask app after receiving POST request and running the code
image = request.files['image']
image variable have type
<FileStorage: 'image.png' ('image/png')>
how can i convert it to Pillow image or open with Image.open() ?
FileStorage is not image type but only wrapper on normal files like PNG/JPG/PDF/Excel/etc. which flask uses to keep information about original files and which gives you direct access to original file - probably as file handler - and Pillow can use it directly to read image (without saving to file, and without using io.Bytes to create file image in memory)
image = request.files['image']
img = Image.open(image) # load with Pillow
print(img.size) # show image size (width, height)
img = img.convert('L') # convert to greyscale
img.save('output.png') # save it
#draw = ImageDraw.Draw(img) # create object to draw figures or text on image
All modules/functions which can use file handler instead of filename (to read file) should read from FileStorage without problem.
EDIT:
Minimal working code - tested with images .png, .jpg, .webp
from flask import Flask, request, render_template_string
from PIL import Image
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def index():
print(request.files)
if request.files:
image = request.files['image']
# pillow
img = Image.open(image)
print(img.size)
img = img.convert('L') # greyscale
img.save('output.png')
return render_template_string('''<form method="POST" enctype="multipart/form-data">
<input type="file" name="image"/>
<button type="submit">Submit</button>
</form>''')
if __name__ == '__main__':
app.run(debug=True)
#furas thank you! Your tip on image.seek(0) worked for me, this was the cause of my issue. My pointer was at the end of file when I was trying to access it after verifying.

Python Flask app posting an image and using cv2.imread function

I made a small python app for face recognition and now I am converting it into a flask application.
#app.route('/save', methods=['POST'])
def save_image():
if request.method == 'POST':
if 'imageFile' not in request.files:
return {"detail": "No file found"}, 400
image = request.files['imageFile']
imageFileName = secure_filename(image.filename)
image.save('./images/' + imageFileName)
image = cv2.imread('./images/' + imageFileName)
image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
face_encoding = face_recognition.face_encodings(image)[0]
np.savetxt('./encodings/' + request.form['indexNumber'] + '.csv', face_encoding, delimiter=',')
return 'saving image'
In the above code I have saved the image posted to the server and read it again using cv2.imread and have later used it to create the face encoding. What I want is to do this without saving the image in the server. Is there a way to directly read the image posted and use like above?

How to display an uploaded image manipulated with PIL without saving to file Django

I am pulling a image from a database to be used as a background and placing a user uploaded image on top of the background using PIL. I would like to display this image to the html page after the transformation is complete without saving to the file system. I have looked at many similar questions, but I am doing something different here. I have tried to craft some code based on the other answers, but I can't get the image to display on the screen after the user submits their photo. How can I get this to work? Here is my code:
from django.core.files.storage import FileSystemStorage
from PIL import Image
from io import BytesIO
import base64
import io
from .models import Samplecards
def imageUpload(request):
if request.method == 'POST':
selection = request.POST['selection']
sample = getImage()
theImage = io.BytesIO(sample.image)
print("DONE")
uploaded_image = request.FILES['img']
foreground = Image.open(uploaded_image).convert("RGBA")
background = Image.open(theImage).convert("RGBA")
background.paste(foreground, (440, 190), foreground)
buffered = BytesIO()
background.save(buffered, format="png")
b64_img = base64.b64encode(buffered.getvalue())
return render(request, 'uploadpage.html', {"image": b64_img})
def getImage():
img = Samplecards.objects.get(image_id=1)
return img
In my html file, I try to display the image like this:
<img src="data:image/png;base64,{{image}}">

upload image using image Path in flask

I want to upload an image file to imgur using the python-Flask. So for this I am submitting an image file from the form and want to upload this file to imgur.
But the point is the example snippets given in the imgur api want the path name of the file that was uploaded. So far I was trying to upload but I am stuck!!
This is my main.py file
if request.method == "POST":
image = request.files.get('myfile') #myfile is name of input tag
config ={
'album':album,
'name':'Catastrophe!',
'title':'Catastrophe!'
}
print os.path.realpath(image.filename) # this line gives me wrong path of file.
print "uploading image..."
#image = client.upload_from_path(filepath,config=config,anon=False)
The commented print statement gives me path like this
/home/suraj/Desktop/FlaskTrials/wallpaper.jpg
But the thing is the correct file path could be anything the user wants to choose image from
How do I get this path. Am I doing the right thing to upload the image to imgur api ?
I would be able to do by making an dir in root folder and adding image to it and then get the filename of that and upload to imgur.
But I was wandering is it possible without saving and image file.
Thanks in advance
It looks to me like you forgot to save the file on the server. Here is a modified version of your code based on http://flask.pocoo.org/docs/0.10/patterns/fileuploads/.
if request.method == "POST":
image = request.files['myfile'] #myfile is name of input tag
config ={
'album':album,
'name':'Catastrophe!',
'title':'Catastrophe!'
}
print "uploading image..."
filename = secure_filename(image.filename)
file.save(os.path.join('/home/suraj/Pictures', filename))
print os.path.realpath(image.filename)
I recommend considering restricting the file names to certain extensions, as suggested by the Flask doc.

Categories