Django と Google Vision API で画像分析ツール（の種）を作る。csvファイルをダウンロードする。

### 目的
- Django と Google Vision API の使い方に慣れる。
- GAE でデプロイすることに慣れる。
- csvファイルをダウンロードする方法を学ぶ。

### コード

[GitHub](https://github.com/takeshikondo/labeldetection.git)

### 動作確認

ファイルを選択しアップロード。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/3af7f1cb-3749-8a01-dbed-c94fc8acbe2c.png)


ラベリング結果。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254604/84889827-5732-3819-a4e1-c356868589f7.png)


### models.py
```python
from django.db import models

class Photo(models.Model):
    image = models.ImageField(upload_to='app1/')
```

### forms.py
```python
from django import forms
from .models import Photo

class PhotoForm(forms.ModelForm):
    class Meta:
        model = Photo
        fields = ('image',)
 
class ImageForm(forms.Form):
    image = forms.ImageField()
```

### views.py
```python
from django.http.response import HttpResponse
from django.shortcuts import render, redirect
from .forms import PhotoForm, ImageForm
from .models import Photo
import requests
import base64
import json
 
def upload(request):
    ENDPOINT_URL = 'https://vision.googleapis.com/v1/images:annotate'
    api_key = 'your_api_key'
    
    if request.method == 'POST':
        form = PhotoForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('app1:upload')
    else:
        form =PhotoForm()
        objects = Photo.objects.all()
        last = objects.last()
    
    if len(objects) > 0:
        with open(last.image.url[1:], 'rb') as f:
            content = base64.b64encode(f.read()).decode('UTF-8')
            image_requests = {
                    'image': {'content': content},
                    'features': [{
                            'type': 'LABEL_DETECTION',
                            'maxResults': 3
                            }]
                    }
                
        response = requests.post(ENDPOINT_URL,
                                 data=json.dumps({"requests": image_requests}),
                                 params={'key': api_key},
                                 headers={'Content-Type': 'application/json'})
        
        description1 = response.json()['responses'][0]['labelAnnotations'][0]['description']
        score1 = response.json()['responses'][0]['labelAnnotations'][0]['score']
        description2 = response.json()['responses'][0]['labelAnnotations'][1]['description']
        score2 = response.json()['responses'][0]['labelAnnotations'][1]['score']
        description3 = response.json()['responses'][0]['labelAnnotations'][2]['description']
        score3 = response.json()['responses'][0]['labelAnnotations'][2]['score']
        
    else:
        description1 = ''
        score1 = 0
        description2 = ''
        score2 = 0
        description3 = ''
        score3 = 0
                    
    d = {
        'form': form,
        'objects': objects,
        'last': last,
        'description1': description1,
        'score1': '{:.3f}'.format(score1),
        'description2': description2,
        'score2': '{:.3f}'.format(score2),
        'description3': description3,
        'score3': '{:.3f}'.format(score3),
    }
        
    return render(request, 'app1/upload.html', d)

def upload2(request):
    from PIL import Image
    from io import BytesIO
    
    ENDPOINT_URL = 'https://vision.googleapis.com/v1/images:annotate'
    api_key = 'your_api_key'
    
    if request.method == 'POST':
        form = ImageForm(request.POST, request.FILES)
        if form.is_valid():
            image = request.FILES['image']
            #image = form.cleaned_data['image']
            
            img = Image.open(image)
            buffered = BytesIO()
            img.save(buffered, format="JPEG")
                        
            content = base64.b64encode(buffered.getvalue()).decode('UTF-8')
            image_requests = {
                    'image': {'content': content},
                    'features': [{
                            'type': 'LABEL_DETECTION',
                            'maxResults': 3
                            }]
                    }
                    
            response = requests.post(ENDPOINT_URL,
                                 data=json.dumps({"requests": image_requests}),
                                 params={'key': api_key},
                                 headers={'Content-Type': 'application/json'})
            
            description1 = response.json()['responses'][0]['labelAnnotations'][0]['description']
            score1 = response.json()['responses'][0]['labelAnnotations'][0]['score']
            description2 = response.json()['responses'][0]['labelAnnotations'][1]['description']
            score2 = response.json()['responses'][0]['labelAnnotations'][1]['score']
            description3 = response.json()['responses'][0]['labelAnnotations'][2]['description']
            score3 = response.json()['responses'][0]['labelAnnotations'][2]['score']
            
            d = {
                'description1': description1,
                'score1': '{:.3f}'.format(score1),
                'description2': description2,
                'score2': '{:.3f}'.format(score2),
                'description3': description3,
                'score3': '{:.3f}'.format(score3),
            }
                        
            return render(request, 'app1/label.html', d)
        
    else:
        form = ImageForm()   
                
    d = {
        'form': form,
    }
        
    return render(request, 'app1/upload2.html', d)
    

def download(request):
    return render(request, 'app1/download.html')
```

### upload.html
```html
<!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Upload</title>
    </head>
    <body>
        <p>  </p>         
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            {{ form }}
            <br><br>
            <button type="submit">アップロード</button>
        </form>
        <br>
        
        <p> </p>
        <img src="{{ last.image.url }}"/><br>
        
        <table border="1">
            <tr>
                <th> ラベル　</th>
                <th>　スコア </th>
            </tr>
            <tr align="right">
                <td> {{description1}} </td>
                <td> {{score1}} </td>
            </tr>
            <tr align="right">
                <td> {{description2}} </td>
                <td> {{score2}} </td>
            </tr>
            <tr align="right">
                <td> {{description3}} </td>
                <td> {{score3}} </td>
            </tr>        
        </table> 
        <br>       
        <br>
        
        <p> データ </p>
        {% for obj in objects %}
        <img src="{{ obj.image.url }}" width="100" height="100"/>
        {% endfor %}
                  
    </body>
</html>
```

### upload2.html

```html
<!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Upload</title>
    </head>
    <body>
        <p>  </p>         
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            {{ form }}
            <br><br>
            <button type="submit">アップロード</button>
        </form>
        <br>
                          
    </body>
</html>
```

### label.html

```html
<!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Label</title>
    </head>
    <body>
        <table border="1">
            <tr>
                <th> ラベル　</th>
                <th>　スコア </th>
            </tr>
            <tr align="right">
                <td> {{description1}} </td>
                <td> {{score1}} </td>
            </tr>
            <tr align="right">
                <td> {{description2}} </td>
                <td> {{score2}} </td>
            </tr>
            <tr align="right">
                <td> {{description3}} </td>
                <td> {{score3}} </td>
            </tr>        
        </table>
        <br>
        <div>
            <a href="{% url 'app1:upload2' %}">戻る</a>
        </div>
                                  
    </body>
</html>
```

### download.html

```html
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Download Sample</title>
    </head>
    <body>
       
        <!--
        <script type='text/javascript'>
            function handleDownload() {
                var content = 'あいうえお';
                var blob = new Blob([ content ], { "type" : "text/plain" });

                if (window.navigator.msSaveBlob) { 
                    window.navigator.msSaveBlob(blob, "test.txt"); 

                    // msSaveOrOpenBlobの場合はファイルを保存せずに開ける
                    window.navigator.msSaveOrOpenBlob(blob, "test.txt"); 
                } else {
                    document.getElementById("download").href = window.URL.createObjectURL(blob);
                }
            }
        </script>        
        <a id="download" href="#" download="test.txt" onclick="handleDownload()">ダウンロード</a>
        -->
        
        
        <script type="text/javascript">
            function fileDownload() {
                var bom = new Uint8Array([0xEF, 0xBB, 0xBF]);
                var data = getData();
                var blob = new Blob([bom, data], { "type" : "text/csv" });
                let link = document.createElement('a')
                link.href = window.URL.createObjectURL(blob)
                link.download = 'output.csv'
                link.click()   
            }
            
            function getData() {
                data = "1, 2, 3, 4, 5"
                return data; 
            }
        </script>        
        <button type="button" onclick="fileDownload()">ダウンロード</button>
                                
    </body>
</html>