jc.jang

가짜 뉴스 만들기 fake-news-generator 본문

프로젝트/가짜 뉴스 생성기

가짜 뉴스 만들기 fake-news-generator

jangstory 2019. 9. 17. 14:15

개요

  • O RLY Cover Generator(링크)를 보고 비슷한 프로젝트를 해보면 재밌을 것 같아서 만들게 되었다.
  • 요즘 많이 쓰는 '속보 ~~~가 ~~~함' 같은 밈을 많이 사용해서 그것과 어울리게 뉴스 속보 짤 생성기를 만들고 싶었다.

  • 구글링해보니 비슷한 영문판 서비스 Break Your Own News(링크)가 있긴했지만, 공부를 위해서 만들어 보기로 했다.

동작 원리

  • headline, content, background image를 입력하면 가짜 뉴스 이미지를 생성한다.
    1. /generator/에 접속하여 form을 /fake_news_generator/에 비동기로 전송
    2. /fake_news_generator/에서 base64로 인코딩된 이미지 문자열을 반환
    3. /generator/의 이미지 영역에 가짜 뉴스를 그려준다.

어려웠던 점

  • 데이터베이스, 파일 서버를 사용하지 않고 이미지를 가공하고 싶었다.
  • 그래서 request.FILES을 다루는 방법을 찾아봤고, Django에서는 Inmemoryuploadedfile 객체로 파일을 갖고 있어서 이를 활용했다.
  • Pillow로 박스와 글자를 써주고 이미지를 base64로 인코딩하고 문자열을 반환했다.
  • 여기서 고생을 많이했는데, base64.b64encode(bufferd.getvalue())만 하면 문자열 반환 시 b'인코딩된문자열'의 형태로 반환되어 템플릿의 이미지 태그에 이미지를 제대로 불러 올 수 없다.
  • request.FILES에서 받은 이미지는 InMemoryUploadedFile 객체이고 
  • 이미지.file은 io.BytesIO 객체, 이미지.image는 PIL.JpegImagePlugin,JpegImageFile 객체이다.
  • 이미지를 다루는 코드를 공유하자면 다음과 같다.
  • views.py

 

from django.http import JsonResponse

from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import base64

from . import forms

def fake_news_generator(request):
    if request.method == 'POST':
        form = forms.GeneratorForm(request.POST, request.FILES)
        if form.is_valid():
            headline = form.cleaned_data['headline']
            content = form.cleaned_data['content']
            background_image = form.cleaned_data['background_image']

            # background_image.file로 파일을 읽어 올 수 있다.
            background_image = Image.open(background_image.file)
            background_image = background_image.resize((1280, 720), Image.ANTIALIAS)

            buffered = BytesIO()
            canvas_im.save(buffered, format='PNG')
            
            # decode를 안하면 문자열에 b''가 붙어 있으므로 반드시 decode해야함 
            img_base64 = base64.b64encode(buffered.getvalue()).decode()

            return JsonResponse({
                'img': img_base64
            }, json_dumps_params = {'ensure_ascii': True})
  • index.html
$.ajax({
    url: '/generator/fake_news_generator',
    processData: false,
    contentType: false,
    data: formData,
    type: 'POST',
    beforeSend: function() {
        $('#fake-news-img').attr('src', "{% static 'image/Spinner-1s-200px.gif' %}");
    },
    success: function(data) {
        $('#fake-news-img').attr('src', 'data:image/png;base64,'+data['img']);
    },
});
  • base64 데이터로 이미지를 나타내려면 src='data:image/png;base64,{{base64데이터}} 형식으로 넣는다.

아쉬웠던 점

  • 이미지를 파일로 저장하고 url을 연결해주는 방식만 하다가 base64로 인코딩하고 값을 던져주는 방식으로 처음 해봤다.
  • 디코딩을 안해서 b''가 딸려 나온다는걸 아는데까지 너무 오랜 시간 걸렸다. 어떤 분께서 크롬 개발자 도구로 확인해보라는 말을 듣고 겨우 찾았다.
  • 공부 목적이 아니었다면, canvas로 그림을 그리는 것을 추천한다.

궁금한 점

  • 만약에 머신러닝같은 연산이 오래 걸리는 작업을 하고 결과를 반환해준다면, celery같은걸로 비동기 프로그래밍을 해야하는건가...?

'프로젝트 > 가짜 뉴스 생성기' 카테고리의 다른 글

이미지 파일만 입력 받기  (0) 2019.10.08
이미지가 회전되는 버그 수정  (0) 2019.09.18
Comments