Flickr Integration Complete! October 11, 2013
It really didn't take too long! What I outlined in the previous post is exactly what it does:
- Check flickr for my photos that were tagged with "jtccom". Download the 2048 pixel wide version of it
- Write JS + Node part of my website which shows, in a queue like manner, an image that hasn't been processed
- Clicking on the image shows a box of where I clicked, where it would be cropped, according to the sizes defined for the header
- Send request to the server, which uses GraphicsMagick to crop it and then create different scaled images based on the sizes defined for the site
Here are some screenshots:
At first, you are prompted with the next image which hasn't been processed
Next, you select the point where you want to crop it. Sizes are pre-determined, so there's no dragging and resizing a bounding box, it knows all the sizes and the size of the images, so it just does it for you
![](https://storage.googleapis.com/jtc-public/static/images/flickrdev/crop-select.png)
Click the process button when you've made your crop selection
Wait a second or two while Node.js and gm (GraphicsMagick) processes your photos.
And GraphicsMagick code in node.js, which is really helpful, and I was able to get it to work on Windows
this.handlePost = function(site, query, finishedCallback){
var tmpdir = path.normalize(site.path + site.config.tempDownloadFolder);
var processeddir = path.normalize(site.path + site.config.processedFolder);
var form = query.form;
var sizes = site.config.imageWidths;
var heights = site.config.imageHeights;
var filename = form.image.substring(form.image.lastIndexOf("/")+1);
var fileParts = filename.split(".");
sizes.sort(function(a,b){ return b - a; });
heights.sort(function(a,b){ return b - a; });
var x1 = parseInt(form.x1, 10),
x2 = parseInt(form.x2, 10),
y1 = parseInt(form.y1, 10),
y2 = parseInt(form.y2, 10);
var w = x2 - x1, h = y2 - y1;
// process first size, use that for base of resizes
var croppedPath = processeddir + fileParts[0] + "-" + sizes[0] + "." + fileParts[1];
gm(tmpdir + filename).crop(w, h, x1, y1).write(croppedPath, function(err){
var sync = new SyncArray(sizes);
sync.forEach(function(size, index, array, finishedOne){
if (index > 0){
var scaled = processeddir + fileParts[0] + "-" + size + "." + fileParts[1];
gm(croppedPath).resize(size, heights[index]).write(scaled, function(x){ finishedOne(); });
} else finishedOne();
},
function(){
finishedCallback({ content: JSON.stringify({ success: true }), headers: {"Content-Type": "application/json"} });
});
});
}
Again, it uses my custom built webserver and the SyncArray object that I also wrote.
Flickr code was pretty simple too. Here's that, accessing the Flickr API (no auth) with Node.js
var http = require("http"),
querystring = require("querystring"),
SyncArray = require("syncarray").SyncArray;
this.getPhotosByTag = function(apiKey, user, tag, callback){
var self = this;
var method = "flickr.photos.search";
var qs = { method: method, api_key: apiKey, user_id: user, tags: tag, format: "json", nojsoncallback: 1 };
var req = { host: "api.flickr.com", path: "/services/rest/?" + querystring.stringify(qs) };
http.get(req, function(res){
var json = "";
res.on("data", function(d){
json += d;
}).on("end", function(){
var photos = JSON.parse(json).photos.photo;
if (photos.length > 0){
var sync = new SyncArray(photos);
sync.forEach(function(photo, index, array, finishedOne){
self.getPhotoSizes(apiKey, photo.id, function(sizes){
photo.url = sizes.filter(function(s){ return s.label == "Large 2048"; })[0].source;
finishedOne();
})
}, function(){
console.log("url = " + photos[0].url)
callback(photos);
})
}
else callback([]);
});
});
}
this.getPhotoSizes = function(apiKey, photoId, callback){
var method = "flickr.photos.getSizes";
var qs = { method: method, api_key: apiKey, photo_id: photoId, format: "json", nojsoncallback: 1 };
var req = { host: "api.flickr.com", path: "/services/rest/?" + querystring.stringify(qs) };
http.get(req, function(res){
res.setEncoding("utf8");
var json = "";
res.on("data", function(d){
json += d;
}).on("end", function(){
var sizes = JSON.parse(json).sizes.size;
console.log(sizes.length);
callback(sizes);
});
});
}
The next step is to update the front end css to include all sizes of a version of the image, and switch between them using the respond.js and media queries. That should be simple, but it's late and I'm going to bed!!
Enjoy! Leave a comment.