Digitising Photos With The Plustek ePhoto Z300 Scanner

Making the transition in moving photos from physical to digital form can be quite an undertaking depending on the volume of photos you have to work with. Traditional flat-bed scanning and Photoshop combinations aren’t really up to the task if you want a process that requires minimal manual intervention. It can all be quite cumbersome, from placing the photo correctly on the scanner to then carrying out any photo enhancements, cropping and exporting. Yes, you get a fantastic digital print but it comes at a cost - time.

If you are really serious in digitising a bulk load of photos, there are a couple viable options:

  1. Photo-scanning service where you post all the photos you wish to digitise. The costs can be relatively low (around 1p per photo) and is good if you have a specific number of photo’s to digitise.
  2. Purchase a photo scanner where photos are scanned manually in a document feeding process, which makes for a less intensive job.

Due to the large number of photos that have accumulated over the years, I preferred to purchase a photo scanner. Sending off photos to a photo-scanning service didn’t seem viable and could prove quite costly. I also had the fear of sending over photos via post where I do not have the original negatives. They could be lost in transit or handled incorrectly by the photo-scanning service. Not a risk I was willing to take. Photos are precious memories - a snapshot of history.

The most ideal photo scanner for a job of this undertaking needs to be sheet-fed, where the photos are fed through a scanning mechanism. There are quite a number of these type of scanners, mostly being document scanners, which isn’t the type of scanner you want. From personal experience I found document scanners lack the resolution required and the feeding mechanism can be quite rough on photos.

I decided to go for the Plustek ePhoto Z300 as it seems to fit the bill at a really good price (at time to writing £170).

Initial Impressions

The Plustek scanner doesn’t look like a scanner you’ve ever seen and almost looks other worldly. Due to its upright position, it requires very little real-estate on your desk when compared to a flat-bed scanner.

All functions are performed from the software you can download from the Plustek site or via the CD provided in the box. Once the software is installed and scanner calibrated you’re good to go.

Software

I’m generally very reluctant to install software provided directly by hardware manufacturers as they encompass some form of bloatware and prefer a minimum install of just the drivers. The software provided by Plustek is very minimal and does exactly what it says on the tin - no thrills!

Just to be sure you’re running the most up-to-date software, head over to the Plustek site.

When your photos are scanned you’ll be presented with thumbnails in the interface where you can export a single or group selection of images to the following formats:

  • JPG
  • PDF
  • PNG
  • TIFF
  • Bitmap

I exported all my scans to JPEG in high quality.

There is a slight bug-bare with the Mac OS version of the software as it doesn't seem to be as stable as its Windows counterpart. This only became apparent after installing the software on my Dad’s computer running on Windows. I noticed when you have collected quite a few scans, the Mac OS version seems to lag and crash randomly, something that doesn’t seem to occur on a Windows machine. This is very annoying after you’ve been scanning over a 100 photos.

The hardware specifications on both machines are high running on i7 processors and 16GB of RAM, so the only anomaly is the software itself. A more stable Mac OS version of the scanning software would be welcome. In the meantime, I would recommend Mac users to regularly save small batches of their scans.

The Scanning Process

The speed of scanning varies depending on the resolution set from within the software, where you have either 300 or 600 dpi to choose from. I scanned all my prints at 600 dpi, which taken around 15 seconds to scan each 4x6 photo, whereas 300 dpi was done in a matter of seconds. I wanted to get to the best resolution for my digitised photos and thought it was worth the extra scanning time opting for 600 dpi.

Even though Plustek ePhoto Z300 is a manually fed scanner, I was concerned that I would have to carry out some form of post-editing in the software. By enabling "Auto crop and auto deskew” and “Apply quick fix” within the scan settings, all my photos were auto-corrected very well even when accidentally feeding a photo a that wasn’t quite level.

To save time in correcting the rotation of your images post-scan, just always ensure you feed the photos top first.

Conclusion

The Plustek Scanner performs very well both on price and performance. I have been pretty happy with the quality when scanning photos in either black and white or colour.

The only thing that didn’t come to mind at time of purchase is scanning is a very manual process, especially when churning through hundreds of photos. It would be great if Plustek had another version of the Z300 that encompassed an automatic feeding mechanism. There were times when I would feed in the next photo before the currently scanned photo had finished, resulting in two photos scanned into one. This didn’t become a regular occurrence once you have got into the flow of the scanning process.

Not having an automatic feeding mechanism is not at all a deal breaker at this price. You get a more than adequate photo scanner that makes the tedious job of digitising batches of photos somewhat surmountable.

Instagram API: Get Access Token In ASP.NET

I've written some code that outputs images using Instagram's Developer API. The code can either output images based on a user's profile or via search term.

As you may already know, in order to get any form of information from any external API an access token is required. Before we dive into some code, the first thing that we need to do is register ourselves as an Instagram Developer by going to: http://instagram.com/developer/.

Next, we need to register a new client specifically for our intended use. In my case, all I want to do is to get all image information from my own Instagram profile.

Instagram API - Register New Client

Here, you will be supplied with Client ID and Client Secret codes. But most importantly, you will need to set an OAuth Redirect URL (or Callback URL) for user's to authenticate your application.

The strange thing I've noticed about the Instagram API is that a callback page is a compulsory requirement. Even if you are planning on carrying out something as simple as listing some images from your own profile where a public users intervention is not required.

I'm not interested in their images, I'm interested in my own. I hope Instagram changes this soon. If Twitter can allow you to retrieve tweets by simply registering your application, why can't Instagram?

From what I've read on Instagram's Google Group's is that an access token needs to only be generated once and they don't expire. But of course Instagram have stated:

"These tokens are unique to a user and should be stored securely. Access tokens may expire at any time in the future."

Just make sure you have some fail safe's in your code that carries out the re-authentication process within your application on the event access token has expired. In my own implementation, I've kept the callback page secret and new access token requests can be made within an Administration interface.

So lets get to the code.

Step 1: Authentication Request Classes

These strongly-typed classes mirror the exact structure of the JSON returned from our authentication request. Even though we only require the "access_token" property, I've added additional information, such as details on the Instagram user making the request.

public class AuthToken
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }

    [JsonProperty("user")]
    public InstagramUser User { get; set; }
}
public class InstagramUser
{
    [JsonProperty("id")]
    public string ID { get; set; }

    [JsonProperty("username")]
    public string Username { get; set; }

    [JsonProperty("full_name")]
    public string FullName { get; set; }

    [JsonProperty("profile_picture")]
    public string ProfilePicture { get; set; }
}

It's worth noting at this point that I'm using Newtonsoft.Json framework.

Step 2: Callback Page

protected void Page_Load(object sender, EventArgs e)
{
    if (!String.IsNullOrEmpty(Request["code"]) && !Page.IsPostBack)
    {
        try
        {
            string code = Request["code"].ToString();

            NameValueCollection parameters = new NameValueCollection();
            parameters.Add("client_id", ConfigurationManager.AppSettings["instagram.clientid"].ToString());
            parameters.Add("client_secret", ConfigurationManager.AppSettings["instagram.clientsecret"].ToString());
            parameters.Add("grant_type", "authorization_code");
            parameters.Add("redirect_uri", ConfigurationManager.AppSettings["instagram.redirecturi"].ToString());
            parameters.Add("code", code);

            WebClient client = new WebClient();
            var result = client.UploadValues("https://api.instagram.com/oauth/access_token", "POST", parameters);

            var response = System.Text.Encoding.Default.GetString(result);

            var jsResult = JsonConvert.DeserializeObject(response);

            //Store Access token in database
            InstagramAPI.StoreAccessToken(jsResult.AccessToken);

            Response.Redirect("/CallbackSummary.aspx?status=success", false);
        }
        catch (Exception ex)
        {  
            EventLogProvider.LogException("Instagram - Generate Authentication Key", "INSTAGRAM", ex);

            Response.Redirect("/CallbackSummary.aspx?status=error");
        }
    }
}

As you can see, I'm redirecting the user to a "CallbackSummary" page to show if the authentication request was either a success or failure. (Remember, the page is secured within my own Administration interface.)

If the request is successful, the access token is stored.

Step 3: Request Callback Page

The last piece of the puzzle is to actually request our callback page by authorizing ourselves via Instagram API. In this case, I just have a simple page with the following mark up:

<p>If Instagram fails to output images to the page, this maybe because a new Authorisation key needs to be generated.</p>
<p>To generate a new key, press the button below and follow the required steps.</p>
<a onclick="window.open('https://api.instagram.com/oauth/authorize/?client_id=<%=ConfigurationManager.AppSettings["instagram.clientid"].ToString() %>&redirect_uri=<%=ConfigurationManager.AppSettings["instagram.redirecturi"].ToString() %>&response_type=code', 'newwindow', config='height=476,width=641,toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no,directories=no, status=no'); return false;" href="#" target="_parent">Generate</a>

If all goes to plan, you should have successfully recieved the access token.

I will post more Instagram code in future posts.