Skin development news 2021/02

It seems whatever might happen around us, we never stop bringing new features to jAlbum and our bundled skins. :) Most of these ideas came from our helpful community which is a tremendous help for us, the development team. Here are a few new things added recently:

Continuous zoom, zooming into the original image

When you aim to show the finest details in a photo the web-optimized slide images are often too small. With this new continuous zoom tool the skin can load the high resolution version on the fly when the visitor zooms enough into an image. However, loading a sizeable image (e.g. a 64 MB panorama image) can be hard for both the graphics system and also regarding the load time. So you might want to optimize (downsize) such images beforehand you add them as “original”.

This function has been made available first in Story skin, but Photoblogger will follow soon. You can use Ctrl + mouse wheel and Numpad + / - buttons too, besides the slider handle below the zoom button:

Skip between levels with previous / next folder links

Originally my skins only jumped to the next folder of the same level. Consequently an automatic slideshow has always stopped at the first time when it didn’t find an adjacent folder. Now the “Skip folder levels” option allows jumping levels up and down. This happens also when you go beyond the last image in a folder (in the lightbox), this way the slideshow won’t stop at the middle of a complex album.

Ask permission to enter a folder

If you’d like to showcase photos not suitable for children, it’s good to have a popup that asks the visitor to confirm his/her age. To make this happen all you have to do is adding a variable, called askPersmission in Edit mode’s right side “Variables” panel. See below!

Select the folder → Edit mode → Variables panel

This is what pops up in the album. (default)

You can also customize these texts by adding value to the variable (right to the name). Format: TitleText::QuestionText::AllowButtonText::DisallowButtonText.

Of course kids can simply click “I’m over 18”, but this is at least a decent attempt to detour them. If you need to set up a strict policy, the only way to do this is by adding password protection to folders through the server’s Control panel. A web page cannot provide any such protection from inside, because anybody can read the folder's URL from the source code.

Better support for media files and practically any file format beyond JPG

As a starter I always design my skins for regular JPG’s – as that makes up 99% of the albums. However, jAlbum albums should be capable of handling videos, PDF’s, moving GIF’s and such, which not always work out-of-the-box, or at least doesn’t work optimally. To test different file formats, and different image types I have set up a test album – you can also peek into:

Related: Using THM files for media (as poster image)

THM files were invented at the early days of jAlbum to provide poster images for video files. Ever since jAlbum is capable of recoding videos and extracting thumbnails, this feature has diminished in importance. Unless you’d like to use an external image, like a real movie poster, or with audio files, which do not have visual representation otherwise. All you have to do is to add a JPG file renamed with the same base name as the media file, use the extension “thm” (e.g. sound.mp3 → sound.thm) and place this file into the Image directory’s appropriate folder. Note, if the media file is linked (i.e. not copied directly into the Image directory) you still have to use the Image directory (Ctrl-Shift-I) – due to historical reasons – otherwise jAlbum will not pick up the THM file.

Related: Using sound clips

Sound clip support is a special feature of some skins (Tiger, Story and Photoblogger for example) by which you can add sound to an otherwise silent photo or video. You should add the mp3 file named the same as the image or video but keep its original “mp3” extension. You need to place this file in the file’s original (linked) folder, otherwise if it’s placed in the Image directory jAlbum will add as separate sound file.

In case of videos sound clips play independently, although the skin tries to synchronize their start/stop events. Here’s an example of such a video enhanced with a sound clip.

In order to check out this sound clip you’ll have to start from the index page; go down the page bottom, and click the “expand” button on the video’s top right corner!

Many users ask why videos (or the background audio) won’t auto-start in their albums. The bad news is, this is by design. Browser makers started to block video auto-start (with sound) in 2019, in order to silence obstrusive ads. This means visitors have to click the “Start/Play” button the first time, even though the gallery author has asked the skin to start videos automatically. Once the visitor has started any video in the album, the next will auto-start, fortunately. The browser maintains the “engagement index” to know which sites the visitor trusts in this regard. You can read more about this “feature” here.

Hiding GPS location

Showing off GPS location publicly might raise security concerns. For instance I wanted to mask my flat’s location in the sample album. Unfortunately, mobile photos do almost always have this GPS data embedded, it’s not enough to trash it through the Edit mode’s Location panel alone. So there is a new setting in Story and Photoblogger skins in the “Image data” panel (above the mentioned Location panel) - called “Hide GPS location”. By using this you can avoid placing the GPS location of a photo on the album’s map.

... and one more thing

We are aware how popular our Chameleon was amongst our users. Unfortunately, Chameleon skin was based on the – since outdated – “table design”, which made the further development practically impossible. Now – due to massive demand :) – I decided to rewrite Chameleon from ground to make it modern and responsive. It’ll take a few months, but hope you’ll appreciate the effort.

Comments are welcome,

Laza

Automate it!

It's sound human nature to avoid doing repetitive tasks. jAlbum was once developed as I didn't want to manually prepare 120 images for the web and create the needed html. Even if jAlbum has a good number of batch processing features, you may find yourself doing manual repetitive work, for instance deleting 1-star images, looking for broken links, renaming files, changing comments or looking for certain images (panoramas for instance). If there is ANY pattern to the work you're doing, then you can automate it using jAlbum's flexible scripting environment. Your aim might not even be to create a web gallery but simply to give your images more descriptive names than "IMG_6624.JPG". How about letting jAlbum rename such images in the format cameraModel+location for instance? I mean, a file called "iPhone SE-New York-7.JPG" tells me A LOT more than "IMG_6624.JPG", don't you agree?

With jAlbum's scripting environment (Tools->System console), you can automate such tasks with only a few lines of code, preferably in the easy-to-learn Groovy language or JavaScript. Long running tasks will automatically pop up a progress indicator allowing you to abort the task, and most operations (not deletions) can also be undone in one go if you change your mind.

Without further ado, let's go through some examples (Nothing beats learning by example). The following scripts operate on all items of the currently opened project, but they can easily be modified to operate on the current folder only, or selected items/objects only (see further down). To try these scripts, copy and paste them to the upper panel of jAlbum's system console (one at a time), then hit the Execute button (CMD/CTRL+E) to execute them (you can also select a part of a script to execute and hit Execute). The result is printed to the lower panel.

Here are some examples to glance at, explanation follows:

 

Sample scripts (Groovy language, requires jAlbum 22)

// Exclude 1- and 2- star images
Work.on(rootFolder.descendants)
.forEach(ao) -> {
    if (ao.rating == 1 || ao.rating == 2) {
        ao.included = false;
        println ao
    }
}

 


// Change 4-star images to 5 stars
Work.on(rootFolder.descendants)
.forEach(ao) -> {
    if (ao.rating == 4) {
        ao.rating = 5
        println ao
    }
}
 

 

 // Exclude videos
Work.on(rootFolder.descendants)
.forEach(ao) -> {
    if (ao.category == Category.video) {
        ao.included = false;
        println ao
    }
}

 


// Find broken links
Work.on(rootFolder.descendants)
.forEach(ao) -> {
    if (!ao.file.exists()) {
        println ao.file
    }
}

 
I hope you find this fairly intuitive. Let's break it down:

  • "Work" is the Java class that's responsible of most of the "plumbing" in these scripts (boring common code): It handles the processing of multiple objects (of any kind actually) and can even process multiple objects simultaneously. In case processing takes time, it pops up an abortable progress dialog. The executed operations are grouped in "undo groups" so it's enough with one (or a few) undo operations to undo all operations. Finally, "Work" makes it easy to prompt the user before action starts and report results.
  • ".on()" - This method tells Work what objects to work on. It can be either an array, List or Stream of objects (i.e. images, videos etc). Typical arguments are as follows:
    • rootFolder.descendants - All objects in the current project
    • currentFolder.children - All objects in the current folder
    • currentFolder.descendants - All objects under the current folder (i.e. including sub folders)
    • selectedObjects - The selected objects
    • TreeCollection.of(selectedObjects) - Selected objects AND their descendants (sub folders)
Note: Excluded objects are skipped when referring to "descendants". To also include these, refer to the TreeCollection API.

  • forEach(ao) - Code to execute for each encountered object. "ao" is a shorthand for AlbumObject - the API used to interface with objects of a project. Check out the documentation for this API in order to know what operations you can perform on each object.


Let's move on with slightly more complex things. Here's first a script that demonstrates how to pass a filtered stream of objects to Work. In this case 1-star rated objects. This script also prompts the user before proceeding and finally shows a result dialog:


// Delete 1 star images. Prompt user and print result
Work.on(rootFolder.descendants.stream().filter(ao -> ao.rating == 1))
.ask("Ok to delete all 1 star images?")
.forEach(ao) -> {
    ao.delete()
}
.showResult()



// Find links
import se.datadosen.io.LinkFile
Work.on(rootFolder.descendants)
.forEach(ao) -> {
    if (ao.file instanceof LinkFile) {
        println ao.pathFromRoot
    }
}


This following script uses the gotoPath() method to navigate the user to the first object found that has a broken link. It also demonstrates how to abort further processing once this first broken link is found:

 

// Goto first broken link
Work.on(rootFolder.descendants)
.forEach(ao) -> {
    if (!ao.file.exists()) {
        window.albumExplorer.gotoPath(ao.pathFromRoot)
        window.toFront()
        throw new OperationAbortedException()
    }
}

 



// Print images and their sizes
Work.on(rootFolder.descendants)
.forEach(ao) -> {
    if (ao.file.exists() && ao.category == Category.image) {
        println ao.pathFromRoot + ": " + ao.ImageInfo
    }
}



// Find panoramas (i.e. images having a width 2 times the height or more)

Work.on(rootFolder.descendants)
.forEach(ao) -> {
    if (ao.file.exists() && ao.category == Category.image) {
        if (ao.imageInfo.width >= ao.imageInfo.height * 2)
        println ao.pathFromRoot
    }
}



// Replace texts in comments. Look for "Adria" and replace with "Kabe"
Work.on(rootFolder.descendants)
.forEach(ao) -> {
    ao.comment = ao.comment.replaceAll("Adria", "Kabe")
    println ao
}



Here's finally a pretty powerful file renaming script: It uses an online location service to map GPS coordinates embedded within images to rename images to the format cameraModel-Place-number. As looking up locations based on GPS coordinates over an external service may be time consuming, this script uses the parallelStream() call to process objects in parallel, and because of the parallelism, we're using an AtomicInteger as number counter to get truly unique numbers for each file:


// Rename files by camera model and place
import java.util.concurrent.atomic.*
counter = new AtomicInteger(1)

Work.on(rootFolder.descendants.parallelStream())
.forEach(ao) -> {
    if (ao.category == Category.image) {
        PlaceService.Place place = PlaceService.instance.getPlace(ao)
        if (place != null) {
            ao.name = ao.vars.cameraModel + "-" + place.name + "-" + counter.getAndIncrement()
        }
    }
}


 Save scripts as "Tools"

If you've made a handy script that you'd like to execute several times, put it into a text file named "preferred name.groovy" and place that file under a "tools" sub directory of jAlbum's "config" directory (See Tools->Open directories->Config directory). Now this script can be executed under the Tools->External tools menu (requires a restart to show up). You can find more useful "External tools" under the "tools" folder of jAlbum's program directory. Inspect these for more inspiration.


I hope this inspires you to investigate the power that lies within jAlbum's scripting environment. You'll find more developer help in our developer center. If you get stuck, post questions to our forum. If you make an awesome script you think others would appreciate, share it in our forum.

What's new on the skin development front?

While we often communicate what’s new with jAlbum, only a few of you follow the advancements in skin development by reading those hidden skin update logs. Here you are some of the most interesting new skin features.

It all started with Story skin, which made custom pages even more useful, by allowing them holding just any (textual) content. This combined with the ability to mix them into the images allowed authoring complex, blog-like webpages, that barely resembled the conventional, square thumbnail grid galleries.

This change, however, made custom pages look broken after changing skins. I realized this when I made a modern sample album, but it turned ugly playing with skins. I guess this is what most new users do too, and might hit user experience badly.

So I revisited all of the bundled skins and modernized them. Tiger skin is still to be done, but Animatics, Lucid, Photoblogger, Projector and Story has received substancial updates recently. Besides changing the custom page layout a lot of other improvements were implemented. Some of these were deep changes like an organ transplant. Hopefully this will result in up-to-date skins, matching modern browser design, that will be also easier to maintain in the future. Here are some of the highlights:

Instant preview on the User Interface

After discovering small browser windows can be embedded into the user interface, I started adding this component to my skins. This makes the effect of certain skin settings instantly comprehensible, saving a lot of guesswork for users.

Custom pages

Embedding custom pages into the index page is now possible with Photoblogger skin too. In the future this possibility will also be added in Projector and Tiger skins.

Embedded custom pages in Photoblogger (embedded). See the same in Story skin!

New custom pages: Calendar and Newimages are now available with all these skins. Calendar collects all images into a calendar-like layout with links to the original folders, while Newimages collect all images created (or modified) within a timeframe. Let me remind you these custom pages work the best placed at the top level, and instead of renaming the file, it’s much better using Title to provide any text as title, e.g. “New images”, which is grammatically correct.

Calendar custom page (embedded)

New images custom page

Optimizations

Such complex pages are hard to load for the browser, so the new updates brings optimizations for quicker and device-specific loading of gallery pages. For instance the skin now preloads the icon fonts and the folder image, so it loads the page with less “Flash Of Unstyled Content” from now on. The thumbnail layouts got also optimized so they don’t jump aroud while loading in Story and Photoblogger skins. I fixed the progressive load function too, which also makes the page be ready much earlier.

Cross-skin translation tool

In order to have more skins receive the most localizations I made a handy tool that gathers texts from other skins, so it saves time for translators. Also helps me finding all the texts used in the source files.

Comments are welcome,

Laza

Presenting jAlbum 23

jAlbum 23 is here, listing a whopping 17 improvements and 15 bug fixes. As always you'll find the full list in our release notes. Here I'll try to give you an overview of the most notable improvements.

Performance

Don't you just hate it when software grows larger and slower over time? We do. Every now and then we therefore revisit the code to see whether it can be made more performant. It's mainly about two things: Doing less (repetitive) work, and doing more work at the same time. People aren't good at this, but computers should, especially if they have multi-core CPUs. You'll find that jAlbum 23 responds faster when opening projects and navigating folders due to better use of multiple CPU cores. We estimate around 30-50% improvement on a 4 core CPU (MacBook Pro 2015). The album making process has also been revisited to eliminate "warm up" costs when doing repetitive album builds: We now keep the script engine between album builds and also keep cached compiled copies of all scripts. We've also gained around 20% better album making performance due to better parallelism (updating a huge "Tiger" skin project). Finally, image filter processing is now also done in parallel to achieve better performance.

Improved image ordering

One guiding principle in user interface design is to not surprise the user. Here I have to admit that we've failed when it comes to image ordering, especially in relation to drag and drop. jAlbum hasn't always positioned newly dropped items exactly where you dropped them, and after a screen refresh, they might have been reordered to match the folder's sort order, but was this expected? Sometimes jAlbum will change the sort order, but was this expected? jAlbum 23 tries to behave in a more predicable manner and give you more control at the same time.

Before explaining further, let me just quickly explain how image ordering in jAlbum works: Historically, jAlbum provided one type of sort order for the whole album (by camera date, alphabetically etc). This is controlled under Settings->Pages and is referred to as "jAlbum ordering". Later, we added folder specific ordering. This ordering can either be in accordance to the global "jAlbum ordering" or something else, like "Camera date ordering". There's also "Custom ordering" which simply means "You decide by drag and drop". Folder specific ordering is controlled under View->Order by.

 So what's new? Apart from fixing bugs, jAlbum now introduces two methods of dropping new files onto a folder. The first method, the "specific drop" positions the newly dropped files exactly where the caret so indicates. This also switches the sort order to "Custom ordering" in order to respect your choice. The switch will be hinted with an animated text so you shouldn't be surprised that the sort order changed. The second way of dropping positions the newly dropped files in accordance with the folder's current sort order. You'll get this behavior if you either drop files onto a folder (either in the folder tree or in the Explorer area) OR if you drop files into the margin area of the Explorer view. This mode is indicated by a "drop rectangle" appearing over the Explorer area instead of a caret. This is actually better explained by this short video. View it!

Click to view video

Specific location drop vs folder order drop

Last used tool

Among the new features of v23 I'd like to highlight the "Last used" tool. This little efficiency enhancer remembers the tool you last executed and binds it to the CTRL/CMD+L keyboard shortcut or Tools->Last tool menu. If you find yourself repeatedly executing a certain tool over a range of images, say straightening several images or adjusting the camera date of several images, then this is a time saver!

 

Bug fixes

Fixing bugs is as (if not more) important as introducing new features. v23 has over 15 fixes. The most notable one being support for Mac OS "Big Sur". I'm also particularly happy that we spotted an ancient bug that caused occasional script errors during album making, typically triggered by instantly making an album after switching skin, which happens if you keep jAlbum's preview window open while switching skin.

 

I hope you're eager to install jAlbum 23. We've arranged 30 new trial days to everyone so you have a good chance to evaluate it. Also remember that this is a free update to anyone who is on a current support & update plan (See Help->About). Download jAlbum 23 today!

 

8 reasons to update to jAlbum 22

In the past 18 years we have never stopped improving jAlbum. The last two years are no exceptions. Here we present what we think are the top 8 reasons to update jAlbum based on recent improvements.

1

Be compatible

The world around us is changing, so are web standards and the use of mobile devices. Today, more than 50% of jAlbum galleries are viewed from mobile devices. Ensure your galleries play well on mobile devices too by using current skins like Tiger, PhotoBlogger, Lucid, Animatics or Projector.

2

Look good

Design evolve too. Ensure your gorgeous images are presented using modern sleek design. Add styling to your image descriptions without HTML knowledge using jAlbum’s embedded visual HTML editor.

3

Save work

Don’t get lost among hundreds of settings. Find the right setting, project or image in a snap using jAlbum’s Search Bar. Enjoy the instant preview offered in our latest skins. Use the new Project Gallery to visually browse web preview thumbnails of your projects.

4

Save time

jAlbum has a Rewritten upload engine providing faster and more robust uploads. We’ve made performance enhancements to both the user interface as well as album making. jAlbum can also make and upload multiple album projects in the background while you continue working with it.

5

Work better

jAlbum’s improved review mode helps you select, compare and rate your top images. The new Details editor gives you better overview of and allows edits to the metadata of your choice

6

Get it right

Use jAlbum’s integrated Multilingual spell checker so your image descriptions are free from typos

7

Save frustration

Don’t fight old bugs or user interface quirks. Update jAlbum to have them fixed. If you still encounter one, write us so we can fix it. jAlbum’s user interface has undergone many small, but important changes over the years that also saves you time and frustration.

8

Save money

Well, almost ;-). We just lowered the prices 20%. On top of that, you get an additional 30% discount for being an existing licensed user. Now’s a good time to upgrade to jAlbum 22!

Check out our new prices!