Monday, October 26, 2015

Extract a subset of an image using ImageMagick

ImageMagick's convert tool (now called magick in version 7) can be used to perform a large number of tasks. Recently, I had to extract out a portion of a large number of images at certain locations and at certain dimensions. Performing this interactively is tedious especially if there are hundreds of photos. Luckily, magick can be used to do the job in batch, with the right parameters.

The input image for extracting a subset

  1. Open up a Command Prompt.
  2. At the prompt, type in the following:

    C:\> magick input.jpg -crop 328x380+6776+192 output.jpg

    Note: 328 is the image width to extract
    380 is the input image height to extract
    6776 is the input image top left pixel x location to extract
    192 is the input image top left pixel y location to extract

  3. Press RETURN.

    The image is extracted out.

Monday, October 19, 2015

Quickly generate a spreadsheet of image properties from a large number of images

Recently there was a need to find out some image properties e.g. the pixel width and height of a large number of photo images. In Windows Explorer, you could enable the Dimensions property to be displayed in the detail view, but you could not do too much with it. You could not do additional calculations on top of the view.

Fortunately, ImageMagick has an identify command to print out information about one or more images. The following shows how to use identify to print out the image file names and dimensions.


  1. Open up a Command Prompt.
  2. At the prompt, type in the command e.g.

    C:\> identify -ping -format "%i,%w,%h\n" *.jpg

    Note: the ping option will prevent the loading of the entire file.
    The format string has place holders for the properties to be printed.
    %i is for the image filename
    %w is for the image width
    %h is for the image height
    And optionally some delimters such as commas between the properties and terminated with a new line character
    '\n'.
    For more information about the string format placeholders, visit http://www.imagemagick.org/script/escape.php
  3. Press RETURN to run the command.

    The information is printed to the screen.

  4. If you want to print the information to a file, type in the following command.

    C:\> identify -ping -format "%i,%w,%h\n" > output.csv
  5. The resultant file can be displayed and further manipulated in a spreadsheet as shown below.



Monday, October 12, 2015

Enabling HTTPS for a Spring Google App Engine deployment

Following the previous post on adding Spring to a Google App Engine application, I wanted to add support for the secure HTTPS protocol to the application. It is quite straightforward to do so by simply adding the security-constraint element to the application's web.xml file as shown below/

  1. Open up the web.xml file in a text editor e.g. c:\MyProject\myapp\src\main\webapp\WEB-INF\web.xml. Add in the following security-constraint elements.

    Note: the example below encrypts the application from the top parent url using the "/*" url pattern.

The development server can only use HTTP, so in order to check the results, the application must be deployed to Google App Engine. As shown below, the Chrome browser shows the HTTPS "padlock" while accessing a URL of the application.
 

Monday, October 5, 2015

Add Spring to a Google App Engine application

Spring is a Java based framework that takes a lot of work out from developing web applications that you can "just run". I tried to install Spring on Google's App Engine platform as a service (PAAS) but there are a few "gotchas".

Google App Engine runs the older Java 1.7 SDK and hence you must adjust the development environment accordingly. Java 1.8 cannot be used otherwise you will encounter no class found when trying to deploy your Spring application. The Servlet API should be version 2.5 only. Once you keep to the above versions, you only need to follow the steps below to add Spring to a skeleton Google App Engine template. For more information on creating the skeleton with Maven, see Google's documentation at https://cloud.google.com/appengine/docs/java/tools/maven.

Creating the skeleton

  1. Open up a Command Prompt. Change to a parent folder where you want to build the project, e.g. C:\MyProjects\.

    C:\> cd \MyProjects
  2. Type in the Maven command to create a skeleton.

    C:\> mvn archetype:generate -Dappengine-version=1.9.27 -Dapplication-id=your-app-id -Dfilter=com.google.appengine.archetypes:appengine-skeleton-archetype

  3. When prompted for the groupId, type in a name space, e.g. com.mycompany.myapp.
  4. When prompted for the artifactId, type in e.g. myapp.
  5. When prompted for the version, type in a value or accept the default.
  6. When prompted for the package, type in a value or accept the default.
  7. When prompted to confirm, type in Y.

    The skeleton is created.
Add the application's Java code and logic
  1. Using your favorite text editor or IDE, create the Java source code in the skeleton project's src\main folder , e.g. Application.java and MySvc.java.
    Application.java with Spring configuration annotations

    MySvc.java with Spring controller annotations. This just prints out a message "Greetings from Spring Boot" when invoked. 


Add in Spring configurations in the pom.xml file
  1. Open up the skeleton's pom.xml file in a text editor.
  2. In the properties section of the pom.xml file, add in a property for defining the Spring version for convenience.

    <spring.version>4.2.1.RELEASE</spring.version>
  3. In the dependencies section of the pom.xml file, add in the all the Spring dependencies you want to use in the application, making use of the Spring version property defined earlier.

    An example listing for the edited pom.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
 
<groupId>com.mycompany.myapp</groupId>
<artifactId>myapp</artifactId>
 
<properties>
<app.id>com.mycompany.myapp</app.id>
<app.version>1</app.version>
<appengine.version>1.9.27</appengine.version>
<gcloud.plugin.version>2.0.9.74.v20150814</gcloud.plugin.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>

<!-- Add a property for Spring -->
<spring.version>4.2.1.RELEASE</spring.version>
</properties>
 
<prerequisites>
<maven>3.1.0</maven>
</prerequisites>
 
<dependencies>
<!-- Compile/runtime dependencies -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>${appengine.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
 
<!-- Test Dependencies -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-testing</artifactId>
<version>${appengine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-stubs</artifactId>
<version>${appengine.version}</version>
<scope>test</scope>
</dependency>

<!-- Spring Dependencies -->
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
 
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>


</dependencies>
 
<build>
<!-- for hot reload of the web application-->
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>display-dependency-updates</goal>
<goal>display-plugin-updates</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<version>3.1</version>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<archiveClasses>true</archiveClasses>
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
 
<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>${appengine.version}</version>
<configuration>
<enableJarClasses>false</enableJarClasses>
<version>${app.version}</version>
<!-- Comment in the below snippet to bind to all IPs instead of just localhost -->
<!-- address>0.0.0.0</address>
                    <port>8080</port -->
<!-- Comment in the below snippet to enable local debugging with a remote debugger
                         like those included with Eclipse or IntelliJ -->
<!-- jvmFlags>
                      <jvmFlag>-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n</jvmFlag>
                    </jvmFlags -->
</configuration>
</plugin>
<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>gcloud-maven-plugin</artifactId>
<version>${gcloud.plugin.version}</version>
<configuration>
<set_default>true</set_default>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.codehaus.mojo
</groupId>
<artifactId>
versions-maven-plugin
</artifactId>
<versionRange>
[2.1,)
</versionRange>
<goals>
<goal>
display-plugin-updates
</goal>
<goal>
display-dependency-updates
</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

Modify the Servlet's web.xml  file to add in Spring configurations

  1. Open up the skeleton project's web.xml file in [project]\src\main\webapp\WEB-INF\ folder in a text editor.
  2. Add in sections for defining the Spring configuration context, listener, dispatcher sections.
  3. In the context-param section's contextConfigLocation param-name, define your controller's class name e.g. com.mycompany.myapp.Application.
  4. In the servlet section's contextConfigLocation init-param, define your controller's class name e.g. com.mycompany.myapp.Application.

    An example web.xml file is shown below
    .
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
 
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>
 
<!-- Configuration locations must consist of one or more comma- or space-delimited 
        fully-qualified @Configuration classes. Fully-qualified packages may also 
        be specified for component-scanning -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.mycompany.myapp.Application</param-value>
</context-param>
 
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
 
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.mycompany.myapp.Application</param-value>
</init-param>        
</servlet>
 
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
 
 
</web-app>


Building and deploying to the development server

  1. Open a Command Prompt. Change directory to the root of the skeleton project e.g. C:\MyProjects\myapp\.

    C:\> cd \MyProjects\myapp
  2. Type in the Maven build command.

    C;\gt; mvn clean install
  3. To run the Spring application in the Google App Engine development server, type in the command:

    C:\> mvn appengine:devserver



    The Spring example can be accessed from a browser as shown below.