Photos from China: Building an Interactive Gallery

Photos from China: Building an Interactive Gallery

- 14 mins

Starting in October 2018, I spent eight weeks in China working on a project (WPI’s Interactive Qualifying Project) for school. While there, I took and collected over 4,000 photos, the vast majority of which I took on the weekends, when we got to travel to places like Shanghai and Beijing, as well as around the city where we stayed, Hangzhou. This post will cover a couple topics: first, a bit about my experiences taking the photos (and travelling in general), and second, how I made an interactive gallery of photographs that allows users to explore where the images were taken.

Photography in China

Film

I decided it would be fun to take a film camera on the trip with me, so my dad sent me one he had, a Canon EOS Rebel, along with a single roll of black and white film, which had expired in 1998. I also managed to find a decently priced pack of 10 rolls of color film on Amazon. Of these rolls, I ended up using six: the black and white and five color rolls. I used the black and white roll first, intending it to be practice, as I hadn’t used a film camera in several years. Despite the expiration date of the film and my inexperience, it turned out fairly well. This is one of my favorite black and white photos:

I took it from the 6th floor of the HDU library, overlooking the many dorms just across the street. I also liked this one, showing the top of the Leifeng Pagoda, near West Lake:

I enjoyed shooting on the black and white film, but I think my results were better with the color rolls. The first place I used color film was at Xianghu, a lake in Hangzhou. Sometimes called the “sister lake” of West Lake, Xianghua had far fewer people and generally didn’t feel like a tourist attraction. I first went over our third weekend in Hangzhou and returned in the second to last, and enjoyed it thoroughly both times, taking some of my favorite pictures while there. Here are three of my favorite film photos from Xianghu (coincidentally, all of bridges):

Somewhat related, but courtesy of Kayla, here is a picture of me taking a picture with the film camera, at Xianghu:

Other than Xianghu, the other film photos that I ended up really liking came from our third day in Beijing, which we spent at the Mutianyu section of the Great Wall of China. Once we finally got there (which is quite the story), the wall was pretty awesome. Because of the weather that day - it was grey and cloudy - I didn’t really expect my film shots to turn out very well. I had to mess with the aperture and shutter speed more than I was typically comfortable with, but in the end, most them turned out pretty well. The aren’t perfect, but I’m generally pretty happy with how the turned out - I feel they captured something about the wall that my digital images just didn’t. Here are a few of my favorites:

Overall, I definitely liked using film. It made me slow down and think about what I was doing. After all, I usually only had 24 shots on the camera per trip. I have five color rolls remaining and I hope to experiment some more with them at some point. The only annoying thing about using film was having to be concerned with X-Ray machines, which were fairly prevalent in China, and of course in the airport. But it worked out and I’m happy with the results.

Digital

I took all of my digital photos using my phone, a Samsung Galaxy S8, which worked out pretty well. For a majority of the time, I used an app called Open Camera. I have been using the app for a few years. I like the flexibility it allows - I can change several settings fairly easily that I typically can’t do on the standard camera app.

One of the features of the app that I had fun experimenting with involved [High-dynamic-range imaging] (https://en.wikipedia.org/wiki/High-dynamic-range_imaging) (HDR). HDR functions by taking several (usually three) images of the same subject or scenery at differing exposure levels (usually overexposed, regular, and overexposed) and merging different features from those images to create a single photo that should more accurately represent what the human eye sees. While HDR is fairly standard in camera apps, Open Camera can save all the three images that go into the final composite (for a total of four images, hence the large number of photos I have). This can is cool because you can see the steps that go into the HDR, and sometimes the high or low exposure photos are pretty cool in their own right. Here is a breakdown of a five of my favorite HDR shots. While I have plenty of other photographs that I like, I think these are cool enough to actually write about!

1. HDR: Bridge at Xianghu

This one is by far my favorite HDR sequence that I took. The first image is the under-exposed shot. Compared to the next one, it’s clearly darker. The second is at standard exposure, or at least close to it. It’s likely what would result from a normal photo. It’s fairly bright and you can make out most details. The third image is over-exposed. Since I was (presumably) standing in shadow, the previous images didn’t provide clear detail of the plants in the foreground. By over-exposing, this image got these details while clearly sacrificing the quality of the bridge and the background. This is the final HDR composite generated from the previous three images by Open Camera. It simultaneously shows the details in the bridge, the water, and the greenery that none of the previous photos could show at once - it’s closer to what I saw standing there. This is where there was some unexpected fun that stemmed from being able to save the three images that went into the composite. I automatically uploaded all of pictures to Google Photos, even the ones I’d probably never share like the over-exposed one above. It was just Google’s default setting. So with the prior four images uploaded, Google worked its magic. It turns out, when Google Photos finds a series of images that it thinks would work as an HDR image, it will use them to generate one. And, being that I had uploaded images taken specifically for the purpose of creating an HDR, it definitely found them - mostly. Instead of using the second (standard) image, it used the resulting HDR, which was also uploaded at the same time. In this case, the resulting photograph is far more vibrant than any of the prior ones, and one of my favorite photos in the whole bunch (although it’s not perfect). Other times, as you’ll see later, the result is a bit more… interesting.

2. HDR: Lotus at Xianghu

Again, here’s the under-exposed image. Like a lot of the under-exposed shots, it resulted in something that looks like a silhouette. Here’s the standard photo - nothing too interesting. And this is the over-exposed shot provided clearer details of the lotus. The resulting HDR image provides a nice view of the lotus, while still including the sun and other background details. Once again, Google worked its magic. Using the prior HDR image to create another one, it created a pretty cool photo.

3. HDR: Forbidden City

Again, the same sequence, at the Forbidden City this time. I’m particularly fond of this first image, the under-exposed shot, as well as both of the HDR images.

4. HDR: Shanghai

I really liked Google’s HDR result from this sequence. Here’s that series of photos in gif form so you can see the transition. You might notice that they don’t line up exactly. That’s because I had to stand still while the app took three different photos, and I can’t do that perfectly. How the merging software makes it so they line up, I don’t know, but depending on how still I stood, there are some noticeable artifacts from the merger.

5. HDR: Suzhou (the really weird one)

Last (and very possibly least), is this fun group from one of our stops in Suzhou. The normal HDR image came out pretty much as expected, but the Google version most definitely did not. There are few other like it, but this one is probably the most odd of the bunch. It’s definitely… different:

Here are links to other HDR images that I liked:

  1. Tiger Hill Pagoda
  2. Xianghu
  3. Summer Palace
  4. Suzhou

That’s it for talking about taking the photos, here’s how I built the interactive gallery:

Building the Gallery

Towards the end of my stay in China, I began winnowing my album of 4,000+ photos down, and managed to reduce it to 2,018 images, which I called my “Best of China 2018”. I shared this album with people, but I wanted to do more. One of my friends from the trip created a video about her experiences, and while I wanted to do something similar, I struggled with the video creation process. And so the project didn’t progress very far.

After C19 midterms, I got the idea of creating a page where visitors could use a map to view explore where I went and navigate through photos I took at these locations. The end result is available here, and I am rather satisfied with how it turned out. I used the open source mapping library Leaflet.js along with map tiles from Mapbox (try pressing ‘t’ to view different tiles). For the images, I used Imgur so I didn’t have to test Github’s limits.

Design

The first thing you might notice when visiting the gallery is that I disabled all map controls for the user. You can’t drag, zoom, or otherwise modify the focus of the map. I made this decision (after experimenting with it both ways) so that, hopefully, the user can focus on viewing the images, not messing around with the map. By disabling the controls, I am attempting to eliminate a distraction. It also simplified it on my end, because I didn’t want a user to expect to be able to drag the map to a new location and view the associated images.

For the display of images, I used modified versions of the tools found here to scale down the images (to varying degrees), and allow the user to click on a thumbnail to view the full version. Images are displayed in a random order (mostly so I didn’t have to think about it) and the tiling is completely “natural” - its just however the browser decides to display them. One interesting thing I added to make the page run a bit smoother is the pre-loading of the five full images before and after the one currently being viewed.

A bit later on, I realized that I wanted to add a few videos, so I tied a few keys (such as ‘b’ or ‘x’) to display six different videos in the lightbox as small easter eggs. Anyway, on to how I processed over 1,000 images for the gallery!

Sorting Images

The first major problem I had to tackle involved sorting the images I had into groups that could be navigated through on the map. Obviously, while it would be cool, having 1,000 photos displayed individually on the map would be impractical. So, I had to group them together.

During my attempts at creating a video, I had already grouped my favorites photos by the general location (Xianghu, Shanghai, etc.), but I need even smaller groups, especially for places like Xianghu. Smaller chunks to consume. First, I tried doing this by hand, looking through times and just trying remember which things were in the same general area. Bad idea. Very time consuming with poor results.

Remembering that Google Photos displays images on a map similar to what I was looking for (but only on mobile!), I turned to Python to extract the location data from the images. After a bit of experimenting (copying code from stack overflow), I created a script that grouped images into groups of images roughly within a .2km radius of a central image. Of course there were a handful of images that lacked location data (mostly the ones from friends), so I manually moved these into groups where it seemed appropriate. I also merged some smaller groups together manually. This is the script I used to do this (it also moved the images into folders specific to their groups to make uploading to Imgur easier):

View geo_sort.py

Uploading to Imgur

The process for uploading the photos went very similar to the previous section: first, I tried doing it manually. This didn’t last very long, as I wasn’t being very patient with Imgur’s desktop client (and I don’t think it liked me very much for trying to upload so many photos). So I wrote a fairly quick script to do it automatically. And it worked! Until it didn’t…

It turns out that Imgur has a 50 image per IP address per hour upload limit that is conveniently left out of their API for checking rate limiting. So I had to build in a counter that had the script sleep for 60 minutes after uploading 50 images. As a result, I had to run the script overnight for two nights in a row. I think it took approximately 22-24 hours total, but it output the image IDs in a nice format that I could use to generate the code needed to actually include the images on the page. The code for uploading to Imgur:

View imgur_uploads.py

Generating Javascript

The easiest part of this project was generating the Javascript for the page. First, I had to take the coordinates and location names and create scopes for each group of images (I created the parent scopes manually):

View gen_scopes.py

I then used the output form the second script to create dictionary entries for each of the images. Each image has a URL associated with it, along with other data, such as its width and height, the scale at which its thumbnail should be displayed (so that I could ‘feature’ images), whether it was taken using film, if someone other that I took the picture, etc. The code for generate this is here:

View gen_image_vars.py

Loading Images

Most of the full size images are rather large and can take a second or two to fully load and render. Because of this, I decided to use a tool I found a couple of years ago called Primitive. Primitive takes an image and generates an SVG approximation using, in my case, triangles. Here’s an original and its approximation using 100 triangles: After some blurring, the SVG (which is 20x smaller than the JPG) can be displayed as a placeholder while the full image loads: