One of my goals for RadLab 2 is to have a local adjustments feature – a way for users to paint an effect onto (or off of) certain areas. This is a fundamentally important part of good photo editing, and the only reason RadLab 1 is useful without it is its Photoshop integration; but RadLab 2 is to be a standalone app, so that means I need to climb that mountain. And I did. Here’s the prototype app, and a brief explanation of what it does:
One feature I always wanted from PicTapGo was some basic adjustment sliders for things like adding brightness or contrast to an image. The thumbnail-driven editing is intuitive, but can also be limiting when you are just looking for basic photo adjustments. And in version 3.0, that’s exactly what I did. It’s my favorite PicTapGo feature now, and I’m really proud of it.
The problem was always getting realtime performance from the image rendering. The Edit screen’s preview was originally displayed by a plain ol’ UIImageView – we render a UIImage, and set the view’s image to update it. Basic stuff. But you can’t do that 60 times a seconds. To get the “strength” slider producing realtime updates with the UIImageView-based display, we would render a full-strength image, and then just adjust the view’s alpha value, letting UIKit do the blending. This was a perfectly fine simulation of what Core Image would do in the final render, but it doesn’t work when you’re simultaneously adjusting 4 different parameters.
Enter GLKit, and GLKView.
PicTapGo has always been pretty snappy. This was a result of some design decisions we made at the outset – we render images at the minimum size needed, do our best to limit the depth of the filter chain at any one point, and “cheat” with the strength slider by using an alpha blend in the UI, instead of re-rendering the image constantly. However, there was still some unnecessary lag in a few places, and in version 3.0, I made a point of cleaning them up.
PicTapGo’s crop tool is a unique beast. The tool I envisioned was inspired by Lightroom’s crop/rotate tool, but needed to work within the limitations of a mobile / touch device interface. The requirements for the this feature were essentially:
- Allow the user to simultaneously manipulate rotation and crop;
- Behave the way the user expects (i.e. if you think it should work a certain way, then it will);
- Automatically adjust the image to ensure the crop rectangle is entirely contained within the the image canvas (no “fill pixels” at the edges or corners);
- Work non-destructively;
- Maximize the displayed size of the image; and
- Provide continuous controls, as well as discrete ones (i.e. sliders and buttons) to facilitate quick and fine adjustments, and to increase precision.
The resulting solution is, I think, still the best crop and rotate tool around, period. There are a lot of subtle bits that make it an intuitive, easy, powerful tool.