Djangoのviews.py で画像をPOSTメソッドで受け取った後、urlopenするときにエラーが出ます。
色々調べたのですが、何をしたらいいのかがわかりませんでした。
python のバージョンは、 3.9.12 です。
OS は m1 macです。よろしくお願いします。
python
1 2def image_upload(request): 3 context = dict() 4 if request.method == 'POST': 5 username = request.POST.get("username") 6 image_path = request.POST["src"] # src is the name of input attribute in your html file, this src value is set in javascript code 7 image = NamedTemporaryFile() 8 image.write(urlopen(path).read()) 9 image.flush() 10 image = File(image) 11 name = str(image.name).split('\\')[-1] 12 name += '.jpg' # store image in jpeg format 13 image.name = name 14 15 16 if image is not None: 17 obj = Image.objects.create(username=username, image=image) # create a object of Image type defined in your model 18 obj.save() 19 context["path"] = obj.image.url #url to image stored in my server/local device 20 context["username"] = obj.username 21 else : 22 return redirect('/') 23 return redirect('any_url') 24 return render(request, 'index.html', context=context) # context is like respose data we are sending back to user, that will be rendered with specified 'html file'. 25 26 27 28 29
#追記
現在出ているエラーは、'NoneType' object has no attribute 'timeoutです。
python
1def image_upload(request): 2 context = dict() 3 if request.method == 'POST': 4 5 username = request.POST.get("username") 6 webimg = urlopen(request.POST.get("webimg")) 7 data = webimg.read() 8 image = ContentFile( data, "webcam.jpg" ) 9 10 # image_path = request.POST.get("webimg") # src is the name of input attribute in your html file, this src value is set in javascript code 11 # image = NamedTemporaryFile() 12 # image.write(urlopen(image_path).read()) 13 # image.flush() 14 # image = File(image) 15 # name = str(image.name).split('\\')[-1] 16 # name += '.jpg' # store image in jpeg format 17 # image.name = name 18 19 if image is not None: 20 obj = Image.objects.create(username=username, image=image) # create a object of Image type defined in your model 21 obj.save() 22 context["path"] = obj.image.url #url to image stored in my server/local device 23 context["username"] = obj.username 24 else : 25 return redirect('/') 26 return redirect('any_url') 27 return render(request, 'index.html', context=context) # context is like respose data we are sending back to user, that will be rendered with specified 'html file'. 28 29
#追記のjavascriptファイル
set attribute 'src'をしないと、写真を撮った後に、撮影されたフレームが画面に表示されないので、2つset attribute しています。
javascript
1(function() { 2 // The width and height of the captured photo. We will set the 3 // width to the value defined here, but the height will be 4 // calculated based on the aspect ratio of the input stream. 5 6 var width = 320; // We will scale the photo width to this 7 var height = 0; // This will be computed based on the input stream 8 9 // |streaming| indicates whether or not we're currently streaming 10 // video from the camera. Obviously, we start at false. 11 12 var streaming = false; 13 14 // The various HTML elements we need to configure or control. These 15 // will be set by the startup() function. 16 17 var video = null; 18 var canvas = null; 19 var photo = null; 20 var startbutton = null; 21 var webimg=null; 22 23 function startup() { 24 video = document.getElementById('video'); 25 canvas = document.getElementById('canvas'); 26 photo = document.getElementById('photo'); 27 webimg= document.getElementById('webimg') 28 startbutton = document.getElementById('startbutton'); 29 30 navigator.mediaDevices.getUserMedia({video: true, audio: false}) 31 .then(function(stream) { 32 video.srcObject = stream; 33 video.play(); 34 }) 35 .catch(function(err) { 36 console.log("An error occurred: " + err); 37 }); 38 39 video.addEventListener('canplay', function(ev){ 40 if (!streaming) { 41 height = video.videoHeight / (video.videoWidth/width); 42 43 // Firefox currently has a bug where the height can't be read from 44 // the video, so we will make assumptions if this happens. 45 46 if (isNaN(height)) { 47 height = width / (4/3); 48 } 49 50 video.setAttribute('width', width); 51 video.setAttribute('height', height); 52 canvas.setAttribute('width', width); 53 canvas.setAttribute('height', height); 54 streaming = true; 55 } 56 }, false); 57 58 startbutton.addEventListener('click', function(ev){ 59 takepicture(); 60 ev.preventDefault(); 61 }, false); 62 63 clearphoto(); 64 } 65 66 // Fill the photo with an indication that none has been 67 // captured. 68 69 function clearphoto() { 70 var context = canvas.getContext('2d'); 71 context.fillStyle = "#AAA"; 72 context.fillRect(0, 0, canvas.width, canvas.height); 73 74 var data = canvas.toDataURL('image/png'); 75 console.log(data); 76 photo.setAttribute('src', data); 77 } 78 79 // Capture a photo by fetching the current contents of the video 80 // and drawing it into a canvas, then converting that to a PNG 81 // format data URL. By drawing it on an offscreen canvas and then 82 // drawing that to the screen, we can change its size and/or apply 83 // other changes before drawing it. 84 85 function takepicture() { 86 // var context = canvas.getContext('2d'); 87 var context = canvas.getContext('2d'); 88 if (width && height) { 89 canvas.width = width; 90 canvas.height = height; 91 context.drawImage(video, 0, 0, width, height); 92 93 var data = canvas.toDataURL('image/png'); 94 photo.setAttribute('src', data); 95 webimg.setAttribute('webimg',data); 96 } else { 97 clearphoto(); 98 } 99 } 100 101 // Set up our event listener to run the startup process 102 // once loading is complete. 103 window.addEventListener('load', startup, false); 104 })();
#追記のhtml ファイル
ここの input id ='webimg'のところがわかってないです。
python
1<form method="POST" name="inputForm" text="" enctype='multipart/form-data'> 2 {% csrf_token %} 3 <div id="camera" class="camera"> 4 <video id="video">Video stream not available.</video> 5 <button id="startbutton" type="button">Take photo</button> 6 <input id="webimg" value="" name="src" type="text" style="display: none;"> 7 <canvas id="canvas"> 8 </canvas> 9 </div> 10 <br> 11 <div> 12 <img id="photo" alt="your image"> 13 </div> 14 <br> 15 <button type="submit" class="button" id="submit">Submit</button> 16 </form>
#スタックオーバーフローでコメントされていた解決策。具体例がなく試行錯誤したのですが、解決できませんでした。