@mrkovalchuk
Junior developer

Как создать изображение из base64?

Добрый день.

Задача: взять SVG, преобразовать его в base64 и сохранить на сервере в формате PNG/JPG.

Python, django.

Django view:
def ajax(request):
    if request.is_ajax():
        data = request.POST['img_data']
        data = data.encode()
        with open("imageToSave4.png", "wb") as fh:
            fh.write(data)
        data = {'status': 'success'}

        return JsonResponse(data)

    raise Http404


Код JS:
d3.select('#saveButton').on('click', function(){
            var svg = document.querySelector('svg');
            var svgString = getSVGString(svg);
	        svgString2Image( svgString, 2*dim.width, 2*dim.height, 'png');
        });

        // Below are the functions that handle actual exporting:
        // getSVGString ( svgNode ) and svgString2Image( svgString, width, height, format, callback )
        function getSVGString( svgNode ) {
            svgNode.setAttribute('xlink', 'http://www.w3.org/1999/xlink');

            var serializer = new XMLSerializer();
            var svgString = serializer.serializeToString(svgNode);
            svgString = svgString.replace(/(\w+)?:?xlink=/g, 'xmlns:xlink='); // Fix root xlink without namespace
            svgString = svgString.replace(/NS\d+:href/g, 'xlink:href'); // Safari NS namespace fix

            return svgString;
        }
        function svgString2Image( svgString, width, height, format, callback ) {
            var format = format ? format : 'png';

            var imgsrc = 'data:image/svg+xml;base64,'+ btoa( unescape( encodeURIComponent( svgString ) ) ); // Convert SVG string to data URL

            var canvas = document.createElement("canvas");
            var context = canvas.getContext("2d");

            canvas.width = width;
            canvas.height = height;

            var image = new Image();
            image.src = imgsrc;
            var out = canvas.toDataURL("image/png");
            image.onload = function() {
                context.clearRect ( 0, 0, width, height );
                context.drawImage(image, 0, 0, width, height);
                canvas.toBlob( function(blob) {
                    var filesize = Math.round( blob.length/1024 ) + ' KB';
                    if ( callback ) callback( blob, filesize );
                });
            };
            send_data(out)
        }

P.S.
canvas.toBlob( function(blob) {
                    var filesize = Math.round( blob.length/1024 ) + ' KB';
                    if ( callback ) callback( blob, filesize );
                });

- хз, зачем этот кусок.

Вот такой base64 возвращается.
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACOgAAASwCAYAAABL+Oe0AAAgAElEQVR4XuzaMREAAAgDMerfNCp+CwI65Bh/5wgQIECAAAEC0AlxTRMgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAQ6PgBAg..............AAAECBAgQIECAAAECBAgQIECAAAECo4BAZ8Q1TYAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQCDP+QSxI11QcQAAAABJRU5ErkJggg==


При записывании нужно что-то обрезать мб? Пробовал убирать: "data:image/png;base64," - не помогает
  • Вопрос задан
  • 1667 просмотров
Решения вопроса 3
trushka
@trushka
Я думаю, у Вас сохраняется в base64 именно svg, а не png, и в файл пишется svg-код с заголовком png.. А чтобы отправить на сервер именно png надо отобразить svg на canvas (можно скрытом), а потом выполнить canvas.toDataURL()
Ответ написан
Sanasol
@Sanasol Куратор тега JavaScript
нельзя просто так взять и загуглить ошибку
sanasol.ws/2017/04/05/vuejslaravel-quill-editor-ha...

для php, но суть должна быть ясна
Ответ написан
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
Во-первых, из js-кода отправляется так называемый data url. Бэкенду из него интересна только часть идущая после первой запятой. Во-вторых, пришедшие на бэкенд данные надо декодировать из base64 в байтовую строку:
import base64

data_url = request.POST['img_data']
data_start = data_url.index(',') + 1
data = data[data_start:]
with open("imageToSave4.png", "wb") as fh:
    fh.write(base64.b64decode(data))

И наконец, приведённый вами пример данных не является изображением. Подозреваю, что вместо точек в середине должны быть реальные данные.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы