Previous Entry Share Next Entry
Release 0.10 -- First cut at Photographs
jducoeur wrote in querki_project
Occasionally I need to poke at my brain, and remind myself that, when I focus, I really can move very fast on this project. Today's example is Photos, a major feature which I started last Tuesday, and released today.

In a sense, we've had photographs from the beginning -- I needed them for my Wedding Space, in the original Querki prototype 18 months ago. But they never worked very well: they were designed to always be individual Things, one per photo, which turns out to not fit most use cases -- when you're building anything more interesting than a wiki, you usually want a photo to be a Property of something, not a separate Thing. And we were storing the photos in the MySQL DB, and serving them through the main Querki server, which never made any sense from a load POV. (It worked that way because it was the easiest first cut, not because it was a good approach.)

I've now rewritten all that from scratch. There is now a first-class Photo Type, which you can build Properties from, same as any other Type. You can create a Property as an Optional Photo, or a List of Photos, just as you'd like. This is going to enable lots of use cases, including the Inventory Management Space (which I need to build before Pennsic) and the Craft Gallery App (which Kate wants, to catalog her cross-stitch projects).

The photos are now stored in Amazon S3, so they get served out nice and fast. That's a bit scary, since that is a real cloud-based service that costs real money. But so far, I believe that the amounts should be modest enough for us to be able to afford it. In the long run, we'll probably limit the amount of photo storage for normal accounts, and have some sort of upsell that allows truly crazy numbers of pictures.

Best of all, you can now take photos directly from Querki on your cellphone or tablet, in the browser, and they import straight into the system. It's not *quite* as elegant as doing so with an app, but it's not far off -- it's quite quick and easy. (It totally made my day when I realized that modern browsers let you do this: we actually may not bother with apps for a while yet, since Querki works increasingly well inside mobile browsers.)

To add Photos to your Things, just create a Property as Optional or List of Photo Type, and somewhere in your Default View use the _edit function:
[[My List of Photos._edit]]
This will display an "Add/Replace Photo" button; when clicked, that shows a dialog box with a "Choose File" button. Clicking *that* button lets you either upload a file or (in a mobile device) use your camera to take a picture. Once the picture is taken, it will automatically be uploaded, and the page will refresh so that the photo displays. This workflow will evolve gradually, but it seems to be a decent starting point. (The technology is slowly improving; once the newer standards for taking photos become more common, we'll begin to use them.)

When you upload a Photo, we automatically generate a Thumbnail version, scaled down to about 100 pixels on a side. This is available through the _thumbnail function: if I have a Property named My List of Photos, then
[[My List of Photos -> _thumbnail]]
will display the thumbnails for each of those photos. Thumbnails are automatically clickable -- when you click on one, it pops up the full-sized photo, pretty much as you'd expect.

Mind, this is just a first cut, and there are a bunch of caveats (all of which exist as official Issues):

Photos are currently limited to a maximum of a megapixel -- if the picture is larger than 1000 pixels on any side, we scale it down automatically. There are several reasons for this. From my POV, the most important is cost control: a 1-megapixel photo is *far* smaller to store and transmit than an 8-megapixel one, which helps keep our costs down. It benefits you, because it means that uploading is very fast (we do the basic scaling in the browser, and then further scale-down in the server once it is uploaded).

And frankly, Querki is *not* intended as a photo-storage service, at least for now, and we're not optimized for it. We have photos for showing as part of the page display of a Thing, and you rarely need more than 1000x1000 for that. I believe you'll often want your pictures much smaller than that, so there is a new meta-Property named "Preferred Image Size", which allows you to clamp the size of the photos to something smaller than 1000. I currently expect to use about 500 for my Inventory Space, and I expect that'll often be appropriate.

Photo Security is weak -- for the time being, Photos are strictly security-through-obscurity: their filenames are long and obscure (essentially based on the hash of the photo contents), and there's no apparent way to list them out, so I don't see any obvious way for someone to simply find your pictures. But that's not the same thing as true security: if someone was sniffing your packets with a Wifi sniffer or something like that, they could certainly find out the URLs and look at the photos.

Eventually, I expect to fix this, although probably optionally: Amazon has a service (the Secure Token Service) that I believe can be used to decently secure photographic content. But it'll come at a cost: if I correctly understand how it works, it will probably slow down page loads non-trivially, since we'll have to talk to Amazon a lot more. So it will probably be optional for Private Spaces. In the meantime, though, please keep in mind that Photos, even in Private Spaces, aren't terribly secure in the grand scheme of things. (OTOH, until we have all-HTTPS access, none of Querki is *really* all that secure. We'll get there.)

Taking a photo with a phone can wind up in the wrong orientation -- to my surprise, when I turn my phone or tablet on its "side" (away from its "natural" orientation), even though the screen shifts appropriately, the photos taken that way come out on their side. Personally, I think that's a bug in the OSes, but it is what it is. It wouldn't be a big deal, but...

There are no photo-manipulation tools yet -- in particular, there is no mechanism in Querki yet to let you rotate a photo. So for now, make sure that you take your pictures in the orientation that is natural for your device.

There is no UI yet for manipulating Lists of Photos -- Lists of Photos are basically add-only at the moment. You can't delete pictures, or rearrange the list. This is obviously going to be a problem for serious use, and is essentially a usability bug, but I don't have time to deal with it right now. (It's going to take a day or two of hard work: photos break a lot of implicit assumptions in Querki, and I'm gradually dealing with the ramifications.) Please feel free to tell me if it's becoming a problem for you, and I can kick it up the priority list.

Photos can not be used in Model Types -- pretty much the same problem: Photos are their own weird little module right now, and not well-merged with the rest of the code. I'm going to have to do a lot of refactoring to get to the point where you can use them anywhere you use any other value. That is definitely the goal, though.

Photos must be JPEG for now -- we simply don't deal with other MIME types such as GIF or PNG yet. I don't think it'll be rocket science to fix, but it's low priority for me personally. Again, feel free to disagree, especially if you have a concrete use case that needs them.

Note that the old "Upload Photo" menu pick has been removed: that was the grungy old mechanism, and has been superceded by Photo Properties. I don't think anyone other than me ever did anything with it anyway.

Now, to build the Lochleven Household Inventory Space, which was the point of this exercise. That will eventually become the basis of a more general Inventory App, which anyone will be able to instantiate (I think it'll be a great showcase for Querki), but for now it'll be the first proof-of-concept for using Photos in a serious way...

  • 1

Stop me if you've heard this one

The rotation thing isn't just phones; most rotated cameras don't rotate the image, they just tag it with a bit of EXIF metadata that says "this image is rotated". Probably something in your pipeline is stripping off the EXIF. If you can get the JPEG data at different stages in the pipeline, you can run it through the Linux command "exiftool -Orientation" to see if it's got its "this is rotated" bit.

Re: Stop me if you've heard this one

Intriguing -- no, I didn't know that. (This image-manipulation stuff is very new to me.)

I want to get at the EXIF data anyway -- we're currently setting the image timestamp as the time-uploaded, but it *should* be the time the photo was taken -- so I'll look for this flag while I'm at it. Thanks!

EXIF already mentioned, skipping that. Have you looked into Mozilla's recent work on making even smaller JPGs with the same resolution? Better compression protocol. (

Photos may not currently support anything other than JPG, but if you offload other image elements using similar flows, then GIF and PNG will be needed as JPG doesn't have support for alpha channels, I seem to recall (transparency).

Have you looked into Mozilla's recent work on making even smaller JPGs with the same resolution?

Hadn't yet -- thanks for the pointer. 15% isn't enough gain for me to complicate the architecture yet (especially as I suspect it appears to be a C library, which would be a PITA for my deliberately pure JVM stack), but it's worth keeping an eye on.

In the course of things, I did notice a tool that claims massive compression without noticeably changing the images -- along similar lines, but much more intense; that may actually be worth my while. But it costs real money, and I believe requires significant processor power (and isn't a simple library), so I'm saying Not Yet on that one.

GIF and PNG will be needed

Oh, totally -- there's already a story to that effect. But AFAICT, the majority of use cases are more interested in photos than anything else, so I'm focusing on JPEG for now. I'll take some time to clean up and generalize that stack when a use case motivates me to do so...

  • 1

Log in

No account? Create an account