Android: pipe(“|”) and ProcessBuilder

As of today there’s no public implementation of the java ProcessBuilder.startPipeline in Android.

So I came out with this quick solution, using Kotlin, to pipe multiple processes in Android:

object ProcessUtil {
    private fun check(process: Process, error: (() -> String)) {
        try {
            if (process.errorStream.available() > 0) {
                process.errorStream.bufferedReader().use {
                    it.readText().also { errorText ->
                        check(errorText.isBlank()) { "${error.invoke()} failed with error: $errorText" }
                    }
                }
            }
        } catch (_: IOException) {
            // ignore
        }
    }

    @Throws(IOException::class, IllegalStateException::class)
    fun pipe(vararg processes: ProcessBuilder): String {
        check(processes.size > 1) { "At least 2 processes are required" }

        var previous: Process? = null
        var result: String = ""

        processes.forEachIndexed { index, builder ->
            val cmdString = builder.command().joinToString(" ")
            println("Executing command $index -> $cmdString")

            if (index > 0) {
                check(builder.redirectInput() == Redirect.PIPE) { "Builder redirectInput must be PIPE except for the first builder" }
            } else if (index < processes.size - 1) {
                check(builder.redirectOutput() == Redirect.PIPE) { "Builder redirectOutput must be PIPE except for the last builder" }
            }

            val current: Process = builder.start()
            check(current) { cmdString }

            previous?.let { prevProcess ->
                prevProcess.inputStream.bufferedReader().use { reader ->
                    current.outputStream.bufferedWriter().use { writer ->
                        reader.readLines().forEach { line ->
                            println("writing --> $line")
                            writer.write(line)
                            writer.newLine()
                        }
                        check(current) { cmdString }

                    } // writer

                    if (index == processes.size - 1) {
                        current.inputStream.bufferedReader().use { reader2 ->
                            result = reader2.readText()
                        }
                    }

                } // reader
            }
            previous = current
        }
        return result
    }

    fun pipe(vararg commands: List<String>) = pipe(*commands.map { ProcessBuilder(it) }.toTypedArray())

    fun pipe(vararg commands: String) = pipe(*commands.map { ProcessBuilder(it) }.toTypedArray())
}

And it can be used like this:

    @Test
    fun testPipe() {
        val packageName = context.packageName
        val result = ProcessUtil.pipe(listOf("ps", "-A"), listOf("grep", packageName), listOf("awk", "{ print $9 }"))
        println("result = '$result'")
        Assert.assertTrue(result.contains(packageName))
    }

Photoshop Extension: Opacity Editor

Today I’d like to introduce an extension I’ve created for Adobe Photoshop: Opacity Editor.

I like to take pictures, ok, I’m definitely not a professional photographer, but I still like to try to be one 🙂

In particular I like to take pictures at night, I like to take pictures of moving clouds, stars.. etc. And then I like to stack all the photos into a single document. The problem is that most of the times this Photoshop document has hundreds, if not thousands, of layers (and we’re talking about 40MP images) and, despite the fact that photoshop can barely survive after I’ve added all those layers to the document, the real problem comes after that.. In order to create a nice stacking effect it’s not just a matter of changing the blending mode of the different layers, but also to change their opacity.

Unfortunately Photoshop doesn’t have an option to manage the opacity of multiple layers at the same time, like, for instance, from 0 to 100 of all the selected layers.. or even more advanced options.

That’s why I’ve decided to make an extension (available here) for this. This is it’s pretty easy interface:

So basically what it does is: you select a bunch of layers in your document, then you create the bezier curve. Once you click on “Apply Opacity” the opacity of every selected layer will follow the designed curve value. Let’s make it easier. If you design a curve like this:

the first selected layer will have an opacity of 0 (completely invisible), while the last layer will have 100 as opacity. (If you’ve selected 100 layers, then the second one will have an opacity value of 1, the third of 2 and so on..)

These 2 images, for instance, have been created using this extension:

 

1200~ pics

 

The second one is the result of 1200 layers stacked together and without that extension I would probably still working on it!

And here’s an example of the Extension in action:

 

For more information and download:
https://www.adobeexchange.com/creativecloud.details.20327.html

Why it’s hard to find Android developers

I’m an Android developer (at Aviary) and a New Yorker since late 2010. I’ve been also an actionscript and python developer for more than 10 years.

I hear this every day. Your New York based company is desperately looking for an Android developer, and it’s damn hard to find one.

And you know what? This is your fault. I mean you, tech startup. Yes, you.

Almost all the startups I know here in NYC have launched their core product for iOS first (most of the PMs I’ve spoken with have said that was because of lack of people or time). And then, maybe, if there’s time… they start to realize they need to have an Android version of their app. But by this point the job is not to “create” something, it’s just a “porting” job. Which, for obvious reasons, is a much less attractive job for developers, just as it would be for a PM or a designer. Continue reading

Floating Action Menu for Android

I’ve just created this simple Android library, inspired from the recent changes to the Google+ app, which introduced a floating action item to the bottom. In G+ the action item appears and disappears based on the page scrolling.

In the same way I’ve created this library, with some more customization options, like the gravity and direction of the floating menu items.

Here’s a video of a sample implementation:

Source code and documentation can be find on the github project page:

https://github.com/sephiroth74/android-floating-action-menu

java.lang.UnsatisfiedLinkError workaround

If you ever worked with native shared libraries in Android you’ve probably already faced the “java.lang.UnsatisfiedLinkError” java exception which randomly seems to happen on certain devices ( actually it’s happening on xperia phones mostly, based on my reports ).
There are a bunch of bug reports in the android project like this: https://code.google.com/p/android/issues/detail?id=35962 or this https://code.google.com/p/android/issues/detail?id=64111.
The problem is that Google basically marked all of them as “resolved”, even if developers are still complaining about it.

Continue reading

More Picasso changes

I recently added more changes to my forked version of the Picasso library.

Delay

Added withDelay(long ms) method in the RequestCreator class. Basically it will delay the load of the passed resource by n milliseconds.

[cce]
Picasso.with( context )
.load( url )
.withDelay( 100 )
.into( image );
[/cce]

Batch toggle on/off

In the original Picasso code all the “complete” events are dispatched using a batch operation, this means that you can have at the same time 3/4 “complete” events being triggered, which eventually can cause lags in the UI.
In this fork the batch is disabled by default and can be re-enabled by using:

[cce]
Picasso.with( context )
.setUseBatch( true );
[/cce]

Fork or download the source from GitHub:
https://github.com/sephiroth74/picasso

Link the library in your build.gradle:
compile “it.sephiroth.android.library.picasso:picasso:+”

Forking Picasso

Recently I started using this nice library, Picasso, for my Android projects.
Basically it’s a library which allows you to load any type of images (local or remote, assets or resources) asynchronously into your ImageView. It will load them in background for you, this not blocking the UI. It has also an internal cache system and it also comes with some useful features like “fade” ( when an image is loaded into the view it will automatically create a fade in effect ), “transform” ( you want to post transform the loaded bitmap ), “resize”, “fit” and more.

You can find a better explanation of the project here: http://square.github.io/picasso/

By the way, long story short, as often happens, when you start to use a 3rd party library you also find it’s limitations and you want to make your own changes to fit your particular needs. In fact I made a fork of this library starting adding my changes.

Here’s a first list of changes I made:

Cache

Added the possibility to use an external cache instance per request.
Example:

[cce]// creating a cache object with 1MB max size
Cache cache = new LruCache( 1024*1024*1 );

// now create a new request which will use this cache object
Picasso.with( this ).load( file ).withCache( myCache ).into( imageView );[/cce]

Remember to clear the cache when you don’t need that anymore ( using cache.clear() )

Generators

Generators can be used to load images which cannot be loaded using the common scheme convention. There are different situations when you need to generate a Bitmap which is not directly related to a file or url or even a real bitmap resource.

In this case you can use the scheme “custom.resource” with a Generator.
A Generator is a simple interface with only one method:

[cce]public interface Generator {
Bitmap decode( String path ) throws IOException;
}[/cce]

So you can use a generator in this way:

[cce]Picasso.with(this)
.load( Uri.parse( “custom.resource://” + file ) )
.withGenerator( new Generator() {
@Override
public Bitmap decode( String path ) throws IOException {
return whatever(path);
}
} ).into( imageView );
[/cce]

Resize

Both the original Picasso methods resize and resizeDimen have been modified in the followings new methods:

[cce]public RequestCreator resizeDimen(int targetWidthResId, int targetHeightResId, boolean onlyIfBigger);
public RequestCreator resize(int targetWidth, int targetHeight, boolean onlyIfBigger);[/cce]

basically you can pass an option to skip the resize operation if the loaded bitmap is smaller than the passed `targetWidth` and `targetHeight`

BitmapFactory.Options

Picasso uses a default BitmapFactory.Options object, every time, to decode the required Bitmap.

I’ve added a method `withOptions` in the RequestCreator which allow you to pass your own Options object which will be used to decode the image.
Example:

[cce]BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.RGB_565;

Picasso.with(this)
.load(file)
.withOptions(options)
.into(imageView);
[/cce]

https://github.com/sephiroth74/picasso