Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   canvas и текст в изображение по клику (https://javascript.ru/forum/events/58016-canvas-i-tekst-v-izobrazhenie-po-kliku.html)

MRJ 31.08.2015 08:53

canvas и текст в изображение по клику
 
Люди, помогите вот с этой фишкой http://stackoverflow.com/a/18549573

На jsfiddle все работает, но когда скачиваю, подключаю jquery - не фурычит что-то. Кто-нибудь скиньте готовый html-код если тот у вас тоже не работает. Спасибо.

Что я делаю не так?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Prototype</title>
    
<script src="https://code.jquery.com/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.6.0.min.js"></script>
 
<style type="text/css">
#container {
    border:solid 1px #ccc;
    margin-top: 10px;
    width:300px;
    height:300px;
}
</style>
  
<script type="text/javascript">
var stage = new Kinetic.Stage({
    container: 'container',
    width: 300,
    height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);


var image = new Image();
image.onload = function () {

    var image1 = new Kinetic.Image({
        x: 0,
        y: 0,
        width: 300,
        height: 300,
        image: image,
    });
    layer.add(image1);

    layer.draw();

}
image.src = "https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";


$("#addbutton").click(function () {

    // simple label
    var label = new Kinetic.Label({
        x: 20,
        y: 20,
        draggable: true
    });

    label.add(new Kinetic.Tag({
        fill: 'green'
    }));

    label.add(new Kinetic.Text({
        text: $("#newtext").val(),
        fontFamily: 'Verdana',
        fontSize: 18,
        padding: 10,
        fill: 'white'
    }));

    layer.add(label);

    layer.draw();


});
</script>
</head>
<body>
<input id="newtext" type="text" value="Hello!">
<button id="addbutton">Any this text</button>
<h2>The added text is draggable</h2>
<div id="container"></div>
</body></html>

рони 31.08.2015 09:20

MRJ,
вы что нибудь про готовность страницы слышали или читали ? типа $.ready или window.onload или строка 81

MRJ 31.08.2015 09:38

:-? я-то тут не причем) код брал оттуда) 81 съехала, каюсь) а что в нем не так? просто я нуб в js))

MRJ 31.08.2015 09:43

Так ?

$(window).load(function(){


о, фурычит теперь )

рони 31.08.2015 09:58

MRJ,
Цитата:

Сообщение от рони
строка 81

скрипт можно перенести, поставить перед body, страница к этому моменту уже загрузится (DOM, html)

MRJ 31.08.2015 17:24

все решено ;)

MRJ 01.09.2015 05:24

Кто знает, он отрисовывает только png? У меня генерируется png даже если исходник стоит jpg. Кто-нибудь знает как изменить?

laimas 01.09.2015 06:53

Цитата:

Сообщение от MRJ
Кто знает, он отрисовывает только png?

PNG, JPEG - это форматы для хранения, а canvas работает с распакованным из формата изображением, которое ни png, ни jpeg, ни что другое, это сырец. А вот получить его на выходе можно уже в формате для хранения, в canvas всего два - jpeg и png по умолчанию. Нужно jpg, тогда, например, canvas.toDataURL('image/jpeg').

MRJ 01.09.2015 07:27

laimas,

А как это прописать здесь??? Изображение вставляется не в canvas а в обычном div все рисуется.. Пробовал ничего не получается (

<script type="text/javascript">
	//<![CDATA[
	$(window).load(function(){
	var stage = new Kinetic.Stage({
		container: 'container',
		width: 500,
		height: 400
	});
	var layer = new Kinetic.Layer();
	stage.add(layer);


	var image = new Image();
	image.onload = function () {

		var image1 = new Kinetic.Image({
			x: 0,
			y: 0,
			width: 0,
			height: 0,
			image: image,
		});
		layer.add(image1);

		layer.draw();

	}
	image.src = "/images/top3d.jpg";

	$("#addbutton").click(function () {

		// simple label
		var label = new Kinetic.Label({
			x: 15,
			y: 10,
			draggable: false
		});

		label.add(new Kinetic.Text({
			text: $("#newtext").val(),
			fontFamily: 'Georgia',
			fontSize: 34,
			padding: 10,
			fill: 'white'
		}));

		layer.add(label);

		layer.draw();

	});
	});//]]> 
	</script>

laimas 01.09.2015 07:52

Цитата:

Сообщение от MRJ
Изображение вставляется не в canvas а в обычном div все рисуется..

И какие тогда проблемы? В этом случае бы будь у вас хоть GIF, в вашем div этот формат был бы и вставлен.

Судя по параметрам, Kinetic отрисовывает изображение, вставляет в него текст (?), и еще что-то, я не в курсе чего, а сделать это он может только используя canvas. Открывайте исходный код Kinetic, ищите в нем где возвращается изображение, и указывайте нужный вам формат.

MRJ 01.09.2015 08:16

laimas,

я открыл их исходный код js и тут же закрыл :-? страшно стало)
там этих "toDataURL" 11 штук :-?

laimas 01.09.2015 08:43

Ну это не проблема, нужно глаза закрыть и страха не будет.

Если в этих методах указан параметр (есть некая переменная), то возможно в плагине можно задавать нужный формат, читайте документацию. Если нет, указывайте сами. Что эти (для чего) 11 методов плагина возвращают, я сказать не могу, сам же метод toDataURL() возвращает изображение в формате data:image/png;base64,... (это по умолчанию), или вернет data:image/jpeg;base64,..., если указать методу jpeg формат.

MRJ 01.09.2015 21:16

laimas,

я сделал, как вы сказали, замену в этом файле везде где есть

toDataURL()

на

toDataURL('image/jpeg')

но это не работает, он все равно на сохранение выводит png (

laimas 01.09.2015 22:06

Цитата:

Сообщение от MRJ
он все равно на сохранение выводит png

Сохранение и вывод, это разные понятия. О чем речь?

MRJ 01.09.2015 23:46

laimas, я все сделал, как вы сказали, потом пытаюсь сохранить уже обаботанную этим скриптом картинку со вставленным текстом на сайте, но в диалоговом окне расширение png у нее

laimas 02.09.2015 03:08

<!DOCTYPE HTML> 
<html>
<head>
<script>
function draw(f) {
    var cnv = document.createElement('canvas'),
        ctx = cnv.getContext("2d"), 
        rdr = new FileReader(),
        im  = new Image(),
        ext = format.value;
        
    rdr.onload = function() {
        im.onload = function() {
            cnv.width = this.width;
            cnv.height = this.height;	              
            ctx.drawImage(this, 0, 0);
            image.src = picture.innerHTML = cnv.toDataURL(ext)
        }
        im.src = this.result
    }
    
    rdr.readAsDataURL(f)
}
</script>
</head> 
<body>
<select id="format">
    <option value="image/png">Format PNG</option>
    <option value="image/jpeg">Format JPEG</option>
</select>
<input type="file" onchange="draw(this.files[0])" />
<div><img id="image" /></div>
<div id="picture"></div>
</body> 
</html>


Как видим, возвращается выбранный формат. Если взять ответ канвы (содержимое picture без data:image/jpeg;base64) и сохранить его, например используя РНР:

file_put_contents('img.jpg', base64_decode(ответ_канвы))


то будет сохранено изображение именно JPEG. Это можно даже проверить так - сохранить полученный jpeg ответ канвы с расширением png и gif. Программы (тот же Проводник, отображение значков), которые определяют изображение не по расширению, а по заголовкам, будут отображать эти изображения без проблем, даже с некорректным расширением. А те что ориентируются на расширение, нет, например, попробуйте открыть их в Фотошоп.

То есть с методом toDataURL(ext) все в порядке, как заказали так и работает. А вот "пытаюсь сохранить", то есть отослать готовое на сервер (?), то это нужно смотреть как это организовано плагином. Работа канвы, это не только drawImage() и toDataURL(), можно получить изображение в буфер и вытворять с ним все что угодно. А программы работающие с графикой работают или с сырыми данными (RAW) или с обработанными, но распакованными. Видеокартам JPEG, PNG и прочий зоопарк тоже не нужен, все распаковывается предварительно и затем подается на соответствующие видео страницы. В среде windows изображения, это аппаратно-независимый раст DIB (Device-Independed Bitmaps).

А для хранения и передачи изображения сжимают с целю уменьшения объема данных, и на каком этапе плагин это делает, и он ли вообще в этом виновник, как это сохраняется, нужно разбираться. Мне этим заниматься некогда, да и не и охота. :) Вы используете этот плагин только лишь для того, чтобы поместить на картинку текст?

MRJ 02.09.2015 06:03

laimas,

да, только чтобы текст разместить и все. мне всего-то нужно, чтобы по клику правой кнопки на сгенерированном изображении, оно сохранялось на комп как jpg. всё.

laimas 02.09.2015 06:51

Цитата:

Сообщение от MRJ
чтобы по клику правой кнопки на сгенерированном изображении, оно сохранялось на комп как jpg

Вы код выше пробовали? Если сохранять изображение из примера на диск выбором из контекстного меню, то браузер предложит формат сохранения тот, что и был заказан у канвы. Что там у вас происходит, темный лес.

И вообще, "да, только чтобы текст разместить и все" и при этом "потом пытаюсь сохранить уже обаботанную этим скриптом картинку со вставленным текстом на сайте", это для чего, "водяной знак" на изображение (хотя до водяного знака этому наложению как пехом до Берлина)?

Если так, то зачем все это нужно? Я понимаю, если что-то визуально контролировать, как-то обрезка изображения, наложение слоев, фильтры, эффекты, согласен. Но такое и без HTML5 успешно делали, но чтобы подключать плагин на клиенте ради сделать аля-digimarc, это слишком, эту мелочь нужно поручать серверу, при загрузке изображений.

И так, конечная задача аля водяной знак?


Часовой пояс GMT +3, время: 16:26.