Generating an image based on other images

2

I have two HTML fields. In each of them, there will be a list of teams. When the user selects the two teams that will play (against each other), I would like to generate an image with the logos of both teams in PNG.

Field 1 X Field 2 = PNG Image with Logo 1 + Logo 2

Is it possible to do this only with JavaScript?

Edited: Really has to be with PHP, because the user will have to download the image, thanks for the other alternatives ...

    
asked by anonymous 01.10.2014 / 22:21

3 answers

4

It is possible, yes, with the Canvas API (HTML5).

However, for security reasons, it is not possible to display the collage result in a <img> tag, nor to download, if at least one of the input images comes from a different domain (server) strong> of the page.

The most important steps are described below. I provided an example *; just pay close attention to safety details; this code can be used both to display the result on the canvas and in the <img> , just by choosing the right lines for the desired purpose.

Creating the canvas

It is indispensable because the images will be glued together on the canvas. Therefore, at this stage, it is important to also set the canvas size (see JSFiddle for example *). If you do not want to display the result on the canvas, but instead in a <img> , simply remove the line from appendChild() .

var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
output.appendChild(canvas); // opcional

Creating elements for input images

Required to be able to request files from the server's input images.

var img_in1 = document.createElement("img");
var img_in2 = document.createElement("img");

Listener of the first input image

As soon as the first image loads, it adds its pixels to the canvas and requests the second image. (To find out where to paste the second image inside the canvas, we already have the width of the first image .)

img_in1.addEventListener("load", function(){
    context.drawImage(img_in1
                     , 0, 0, img_in1.width, img_in1.height
                     , 0, 0, img_in1.width, img_in1.height
                     );
    img_in2.src = "/imagens/img2.png";
});

Second input image listener

When the second image loads, this code places it next to the first image on the canvas. If both images are from the same page domain, you have the option to display the collage result in a <img> instead of the canvas .

img_in2.addEventListener("load", function(){
    context.drawImage( img_in2
                     , 0, 0, img_in2.width, img_in2.height
                     , img_in1.width, 0, img_in2.width, img_in2.height
                     );
    // Se as imagens vierem do mesmo domínio da página:
    img_out.src = canvas.toDataURL("image/png");
    botao.href = canvas.toDataURL("image/png");
});

Requesting the first input image

Unleash the whole process; if the first image is not loaded, none of the listeners will be warned and nothing will happen.

img_in1.src = "/imagens/img1.png";

I hope I have helped!

JSFiddle for example : updated to work with JSFiddle's own images, thus escaping from the constraint security.

Edit : I have two comments to make:

  • This method is robust . You can make very complex transformations with the images, thanks to the canvas, and also make the resulting assembly available for download at the end of the process.

  • @Jader method may be easier . If the goal is a simple assembly, intended only for the "static" view on the page itself, the CSS method uses much less script (JS).

01.10.2014 / 23:53
3

I did not really understand the real need to generate an image, my suggestion is to mount the frame with CSS overlapping the images, something like this:

HTML:

<div class="campo" style="background-image:url(ENDEREÇO DA IMAGEM DE FUNDO)">
    <div class="time1" style="background-image:url(ENDEREÇO DA IMAGEM DO TIME 1)"></div>
    <div class="time2" style="background-image:url(ENDEREÇO DA IMAGEM DO TIME 2)"></div>
</div>

CSS:

.campo {
    position: relative;
    width: 660px;
    height: 495px;
    background-size:cover;
}
.time1, .time2 {
    position: absolute;
    width: 128px;
    height: 128px;
    top: 230px;
}
.time1 {
    left: 150px;
}
.time2 {
    right: 150px;
}

Note: I chose to put background-image in the style parameter, because it is easier to work with dynamic images because to put in CSS rules would require at least one class for each team. ..

See working on JSFiddle

    
02.10.2014 / 01:48
3

In general, it is not possible to generate Javascript files when it runs in the browser. If that were possible, we would have a security breach.

You can generate the file in PHP and upload it to the browser. In that case I hope someone more PHP expert will leave an answer on how to do this (my upvote will be guaranteed).

Or you can load two PNG's with the transparent background, each with a team's coat of arms / logo. This saves processing because you can have all the images already stored on the server. The only effort is to hit CSS.

As a variation on this second alternative you can play around with the HTML 5 Canvas , but many people they think that this is not a good idea because their application will not work for a number of people (more or less the population of Antarctica) who can not or do not know how to update Internet Explorer, which already supports this even in obsolete versions.

    
01.10.2014 / 23:09