My task is to give the user an easy way to select an image from their file system. But I need to keep things efficient for the CloudKit database and I have a specific design spec for how the images are displayed in the final product. Users are free to choose any image but the width and height must meet a minimum pixel size and the final image must adhere to a specific aspect ratio. In my case, I want square images at 440px by 440px.
I jumped in and started working with HTML’s
<input> tag using the type: file. The input appears as a button with a label that identifies a chosen file. It’s an easy-to-implement feature but it comes with drawbacks. The developer has almost no ability to style the button and label it.
But a button isn’t enough, I also want a drop zone to allow a user to drag and drop an image file. Drag events are another HMTL5 feature that are relatively easy to implement. I added drag event handlers to a drop zone
<div>. The ondrop handler passes in an event with a dataTransfer.files property.
Conveniently, the ondrop event can piggyback on the file-input onchange event handler function. A newly instantiated fileReader object will process the file as an arrayBuffer.
The overlay slides side to side and highlights the final cropped composition.
Most of my time went into this aspect of the work. It involves two overlapping
<canvas> elements (one to hold the selected image and the other to render an overlay box to indicate the cropped composition) and a container
<div> to manage the mouse or touch events to move the overlay box.
When the image is loaded, the
<div> change size to accommodate the aspect ratio of the selected image. A portrait oriented image will increase the height while a landscape oriented image will increase the width of the tags. It requires a final function to read the pixel dimensions from the selected files. No small task as you may know if you’ve ever tried to read the technical spec for evaluating the raw data of a JPEG. There’s a possible EXIF IFD header marker with an optional SubIFD marker and 16 available Start Of Frame markers — each of which may or may not have pixel dimension data that could refer to the actual image or it could refer to the thumbnail image (augghhhh!).