PHP - Create image from other images - php

I want to allow a user to drag some images into a div (using jquery ui draggable / droppable)
When they have positioned the images they can hit save and the content of that div (the images in their relevent positions) is saved as one large image.
Is this possible?
or would I need to store the positions of each element / image 9somehow) then "re-create" the positons that way?

You would need to store the location (x, y, z if that matters) using javascript, and then pass those values, as well as the images to your server-side php code, where you would use imagemagik to create the image.

It's definitely possible but may be unnecessary, as you say you could simply store the position of each div and reconstruct the composite image in HTML later. That would be simpler.
You tagged ImageMagick here but you wouldn't need it - the standard PHP GD functions would be perfectly adequate.
So you'd need something like:
Javascript for dragging and dropping images
AJAX to save the position of each (x, y and a z-index) to the server
When viewing the image later, simply re-render the divs as they were saved

Related

Approach for storing image crops

We have a custom built CMS which allows for image uploads. In the CMS we have implemented
jCrop. When cropping an image (with GD in PHP), we are storing the original image name and crop image name in the database (MySQL), aswel as the original image and crop image on the server.
When we need an alternate crop, we use PHP to create another crop of the cropped image (and save it to the server). Because such an image has now been processed by GD twice, the result often looks bad.
A possible use case: in the CMS we manage persons. Each person can have an image. Since persons are usually shown in portrait mode, we let the user crop in portrait. On the website this works out fine, but on the mobile website, we actually need a square image. Hence we need two crops.
Lately we've been wondering how we could improve our crop workflow. Would an approach of only storing crop coordinates in the database work on the long term? What is a common approach of dealing with crops?
Thanks in advance!
I would use this approach:
Upload an image. Assign it an unique ID (i.e. an MD5 hash of the name).
Let the user crop it, store only the coordinates and image name in the db
Store the cropped image, give it a filename that is made for example out of the original file name plus the coordinates of the crop.
In this way you will be able to retrieve the cropped image only by knowing it's original name and the coordinates of the crop. In addition an exact duplicate of any crop would not be stored.
Example:
md5('image.jpg' . $crop->x0 . $crop->x1 . $crop->y0 . $crop->y1);
Would an approach of only storing crop coordinates in the database work on the long term?
Not if by that you mean you would also do the cropping each time the picture is requested. That puts unnecessary load on both your server (doing the actual cropping on-the-fly each time) and on the client as well (because there will be no caching of those dynamically generated crop images, unless you implement that on top of the whole thing).
Since persons are usually shown in portrait mode, we let the user crop in portrait. On the website this works out fine, but on the mobile website, we actually need a square image. Hence we need two crops.
Maybe a better approach would be what f.e. Facebook does in some places: Instead of cropping an image to be square server-side, the just have the client load the non-square version – and then let the client do the “cropping” by simply displaying the image as a positioned background image within a square element …

I want to put number on a image dynamically

I want to put number on a image dynamically.
Take two div's. Set backgroung image for one div and put some number on another div. Place the second div on first div by using css properties like position, z-index
There are 2 ways of doing that:
1.) In the client-side:
You can use the HTML5 CANVAS API. This API allows you to draw arbitrary shapes and images inside a canvas element that is rendered into the browser. So to solve your problem you could load an image inside the canvas and after that draw a number on top of it.
2.) In the server-side:
You will load the image and after that draw the number inside of it using a server-side application. Eg. an application developed using PHP, ASP.NET, Python, etc. In PHP you can use the GD library to do that.

Export div content to image

Currently I'm working on a project in which user of website can design a giftwall by drag and drop of gifts. Drag, drop and sorting works perfect and I'm able to store generated giftwall into database. On recipient side system lists all the gift images in the same sequence sender sent so it visually looks like a giftwall. I want to allow users to store this giftwall into a single image so they can store their giftwalls into image album. In current system it lists all individual gifts into a individual div resided in main wrapper div. How can I export this wrapper div to image so it looks same as HTML. Any help will really be appreciated. Waiting for reply.
Thanks!
I don't know if there is a way by using pure javascript, but you can generate the image on your server and send it back.
I have never heard of saving browser's viewport to an image file via JS. I think it's only possible vie creating SVG or using HTML5 canvas.
I asked exactly the same thing a while back.
HTML div to screenshot?
The conclusion is... it is not possible with JS. Questionably possible from PHP also.
Use can use an online service for screen capture, like browsershots, but its not in real-time, and doesn't render everything well.
I used a workaround for my situation.
Recreated all the DOM/HTML elements which create the image (load parameters form database, and generate the DOM). Wrap everything in one container div, and zoom it out to the size you need.
I know, not the prettiest solution, but the only solution I could get to work.
Using <canvas> you can create image that will looks similar to how it looks on the page. Try it this way:
Get the size of wrapper <div> and create the same canvas element. Then get the position of each image in the div wrapper and draw that image on canvas at the same position with the same size.
Things may be harder if you need to draw additional controls, like button or textbox.
All modern desktop browsers suport <canvas> now.
You can either use html2canvas, which isn't perfect yet. Or store browser offsets of elements in div and then with GD or ImageMagick combine them into an image
Maybe this could be of use: http://html2canvas.hertzen.com/

Crawling custom URL's for images and resizing them via AJAX

I'm building a web app where users can store links, with 200x200 pictures associated. By default, I'd like to crawl the link for images and then return thumbnails of the biggest ones (from which the user can select the "official" thumbnail). I want this all to happen via AJAX. My question is: what is the best way to do this?
Currently, I'm using the PHP Simple HTTP Parser to scan a URL. I then find the src attribute of all the <img> tags, use getimagesize to store the image size located at that URL, sort the array from biggest to smallest and return the top 5 biggest image URL's via AJAX to the client. Then the client sends a different AJAX request for each one which makes a server-side ImageMagick script download and cut the image to a thumbnail, save it in a temporary folder and then return the URL of this thumbnail, which the client finally loads on his browser.
Needless to say, this is a little complicated and probably really inefficient. Running this process on http://en.wikipedia.org takes about 10-15 seconds from start to finish. I'm not certain there are any more efficient ways, however.
I'd do it in one AJAX request, with the script automatically resizing the biggest 5 images on the first pass, saving them, and returning a JSON array with the resized image URLs for the client.
You should probably use PHP's DOMDocument class to grab/parse the html page.
getimagesize() means you have to download each image and process them. Perhaps you should consider simply showing the user ALL images, by simply placing img tags that link back to the original HTML page. You could size these however you like using the tags. This way you do not have to download/process a single image until the user has actually selected one for the thumbnail.
Interested if / how you solved this?
In the end I looped through the images doing getimagesize() until both height and width were over a certain size, and then broke the loop.
This way its slightly more efficient as it only downloads as many images as it needs

ALT text for images in HTML

We are working on a website that has tons of images and one of the requirement is to have ALT text for each image (JPG, JPEG, PNG, GIF etc). So whenever the HTML shows and image the ALT text for that image is also written to HTML along with IMG SRC.
After our discussion with developers the solutions that turned up are
1) Create a new table to hold all these image names. Then each time the image is used a db lookup is done and appropriate ALT text is added.
2) Another solution is to write some EXIF info into each file and each time they are used the EXIF info of the file is read and added to HTML as required.
Any suggestions on how to proceed. There are a lot of images so we are looking for the best solution with least load on server and loading time.
Additional info - We run PHP on our server to select images etc.
Thanks
I'ld rule out EXIF as it does not support PNG and GIF.
The db lookup sounds okay (to me) and would scale okay (as long as you did it cleverly). For example you should try to reduce lookups as much as possible.
You might even already have some of this data, and it would be useful to have data about the images anyways
I would recommend storing it in the database because I am sure you have to maintain records of these images, adding another column to a table is little work. Also, if its inside the database you can perform searches on the alt text in case you want to have such a feature.
If you wan't to give the images an alt text, it should be something that works correctly if the image is not there.
I shouldn't be "image's alt text", or "image.jpg". Rather it should be something like "Stackoverflow.com has a lot of questions and answers." when showing a SO screenshot. But if your image can't have a meaningful alt text, then just make alt="", and move on, sometimes it's simply better to give no alt text than giving a bad alt text.
Because of this, you should store the alt text for every image that means something, and not put meaningless alt text (ruling out EXIF information).
If you can live with the alt tags matching the name of the file, you can use some javascript to get all the images and add an alt tag based on the name of the file.
Something like this:
//get all the img tags
var images = document.getElementsByTagName('img');
for (i=0;i<images.length;i++)
{
//get the filename from the src
filename = images[i].src.substring(images[i].src.lastIndexOf('/')+1,images[i].src.lastIndexOf('.'));
//do any formatting here
filename = filename.replace('_',' ');
//set alt/title tags
images[i].setAttribute('alt', filename);
images[i].setAttribute('title', filename);
}
I would avoid option 2 because if you wanted to update the alt text you would need to write to the image file each time, also, if you wanted to process the images eg. generate thumbnails, the meta-data might be lost.
Option 1 seems the most logical, and if you're querying for filenames from a DB, then just get the alt text at the same time.
Maybe third option:
store ALT text in filename :)
While both solutions seem fine to me the question about required load is a bit tricky: if you get the images from a database anyway I'd store the alt tag values in the database as well. If the files are served from a directory it depends on if you are using a database at all. If you don't use a database going the EXIF route sounds like a reasonable alternative, but might create more load than using an additional database as you need to open each file to retrieve the EXIF data.
In short, go the database route if you already use a database.
I would suggest the database option, because the EXIF option will become a problem if somehow an image has to be switched with another image (transferring EXIF data is not trivial), plus parsing a lot of image files on each request would be very resource consuming.
But be it with the database or the EXIF option, I would strongly suggest that you generate a php file acting as a cache, with an associative array of image_name => alt_text, because you don't want 30 sql queries on each page load. The php file would be included as a bootstrap, so every script would have acces to the associative array, via a global variable for example.
And you would have a script that generates this file, so whenever an alt text is changed, you can easily regenerate the cache file containing the associative array.
Honest question: do you really even need to create a new table? If you're using a PHP upload mechanism anyway, couldn't you simply add a new field to the database and add the alt text, then link it as a variable as needed? The PHP would be very simple from there. Just a thought!
If you already have a database (which I presume you do), then don't add a whole new table, just add a column to the existing table where your images are. Then you can just get all the information with the same query you populate your page with. I believe this is the best option.
When you say "a lot of images", how many are we talking about? Hundreds, or thousands?
If you're in the hundreds, I would just create a PHP file with an array of the imagePath/altText pair. Then include this PHP file wherever you are referencing the image. To abstract the implementation, have a method in the PHP file to return the altText given the complete image path.
$texthash = array(
"/some/path/imageName.png" => "some alt text"
, "/some/path/imageName2.png" => "some other alt text"
);
function get_alt_text($imgpath) {
return $texthash($imgpath);
}
This strategy is fast and will not slow down your pages as long as the number of images is still relatively small. The only tricky part is making sure you keep the array sorted by image path as new images are added.
Once the number of images gets large enough that this method is slowing down performance, move the information to the database, and change the method in the PHP file to query the database. Since you've abstracted the implementation, you won't need to change any of the referencing PHP files.
Also make sure you are HTML-escaping the alt text before using it in the HTML.

Categories