Сохранение изображения, полученного с веб-камеры
Я создаю проект Django, в котором мне нужно сделать снимок с веб-камеры, а затем сохранить его в базе данных и в виде файла. Я сохраняю исходный текст в базе данных, но у меня возникают проблемы с сохранением его в файл. Вот мой код:
html:
<form method="POST" action="{% url 'takePhoto' %}" enctype="multipart/form-data">
{% csrf_token %}
<video id="video" autoplay ></video>
<canvas id="canvas"></canvas>
<input type="hidden" name="photo" id="photo" value=""/>
<button id="startbutton1" class="btn btn-outline-secondary btn-sm">Take Photo</button>
<button id="submit" type="submit">submit</button>
<script src="{% static 'scripts/script.js' %}"></script>
javascript:
(function() {
var width = 320;
var height = 0;
var streaming = false;
var video = null;
var canvas = null;
var photo = null;
var startbutton1 = null;
function startup() {
video = document.getElementById('video');
canvas = document.getElementById('canvas');
photo = document.getElementById('photo');
startbutton1 = document.getElementById('startbutton1');
navigator.mediaDevices.getUserMedia({video: true, audio: false})
.then(function(stream) {
video.srcObject = stream;
video.play();
})
.catch(function(err) {
console.log("An error occurred: " + err);
});
video.addEventListener('canplay', function(ev){
if (!streaming) {
height = video.videoHeight / (video.videoWidth/width);
if (isNaN(height)) {
height = width / (4/3);
}
video.setAttribute('width', width);
video.setAttribute('height', height);
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
streaming = true;
}
}, false);
startbutton1.addEventListener('click', function(ev){
takepicture();
ev.preventDefault();
}, false);
clearphoto();
}
function clearphoto() {
var context = canvas.getContext('2d');
context.fillStyle = "#AAA";
context.fillRect(0, 0, canvas.width, canvas.height);
var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);
}
function takepicture() {
var context = canvas.getContext('2d');
if (width && height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
var data = canvas.toDataURL('image/png');
photo.value=data;
} else {
clearphoto();
}
}
window.addEventListener('load', startup, false);
})();
просмотров:
def takePhoto(request):
print("works")
if not request.session.get('logged_in'):
return redirect('/appChallenge/login')
if request.method== 'POST':
user = User.objects.get(username=request.session["username"])
img = request.POST.get("photo")
image = img
imagePath="/media"
a=str(img)
image = image.save(f"{imagePath}/{a}.png")
imgInfo= Image(user=user, img=img)
imgInfo.save()
print("works")
return render(request, 'page.html')
Когда я нажимаю кнопку submit, появляется сообщение "'str' object has no attribute 'save'". Пожалуйста, помогите. Спасибо.
Если ваш js/html код работает, вы получите необработанные данные изображения, закодированные в base64 в вашем представлении 'takePhoto'. Попробуйте
print(img)
, чтобы увидеть что-то вроде "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAADwCAYAA...."
Возможно, вы увидите только "iVBORw0KGgoAAAANSUhEUgAAAUAAAADwCAYAA...."
без метаданных.
Так что ваш 'img' - это просто строка с base64 закодированным значением, у которой нет метода 'save'.
Во-первых, вам нужно избавиться от "data:image/png;base64," в необработанных данных изображения, если строка изображения содержит его. Это метаданные, и base64 не может их декодировать. Это можно сделать на стороне front end:
var data = canvas.toDataURL('image/png').replace(/^data:image\/png;base64,/, "")
Or back end:
img = request.POST.get("photo").replace('data:image/png;base64,', '')
Далее необходимо использовать django ContentFile для создания файлоподобного объекта. Вам нужно имитировать файл с помощью его метода .read(). Также необходимо декодировать данные изображения в кодировке base64:
import base64
from django.core.files.base import ContentFile
def takePhoto(request):
print("works")
if not request.session.get('logged_in'):
return redirect('/appChallenge/login')
if request.method== 'POST':
user = request.user
# remove meta data from base64 encoded data, you can also
# use 'split(',')[1]' to remove all before ','
img = request.POST.get("photo").replace('data:image/png;base64,', '')
# create a file-like object with your image data
image_file_like = ContentFile(base64.b64decode(img))
imagePath="/media"
# first you need to create object
image = Image(user=user)
# and then save image into your model object
# note: only if your 'img' field is 'ImageField' or similar
image.img.save(f"{imagePath}/{a}.png", image_file_like)
image.save()
print("works")
return render(request, 'page.html')
Надеюсь, я ничего не забыл