Copyright 2013 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
This sample application is not an official Google product.
Smashpix is an image manipulation application that is built on Google's Cloud Platform. Smashpix combines several applications to showcase how developers can connect several components of the platform together.
- Backend Server (Google App Engine + Google Cloud Storage)
- Command line daemon (Google Compute Engine)
- Mobile Application (Android)
The setup instructions in this README are the same as the ones you will find in the corresponding Google App Engine server code. You will need both packages for this sample to work.
Programming Languages:
- Java
- Python
Google Components:
- Google App Engine
- Google Cloud Endpoints
- Google Cloud Storage
- Android
- Make sure you have Java installed.
- Download and configure Eclipse.
- Download and configure the Google App Engine Python SDK, 1.8.8
- Download and configure the Google Plugin for Eclipse for your IDE version
- Download and configure the Android SDK, 20131030
- Download and configure the Google Cloud Storage command line tool, gsutil, 3.37
- Download and configure the Google Compute Engine command line tool, gcutil, 1.12.0
- Create a project using the Google Cloud Console
- Enter a project name and project ID, [PROJECT_ID]. The project ID will be your Google App Engine ID, [APPENGINE_ID].
- Select "Compute Engine" from the main project console. You will need to enable billing to use Google Compute Engine.
- Select "APIs & Auth" from the main project console. Enable the following APIs under "APIs"
- Google Cloud Storage
- Google Cloud Storage JSON API
- TaskQueue API
Create client IDs to allow authentication and authorization between components, Using OAuth 2.0 to Access Google APIs.
- Select your project in https://cloud.google.com/console/
- Select "APIs & Auth" followed by "Registered apps" (Left navigation)
- Click the "Register App" button
- Enter "Name" of the application
- Under "Platform" > Select "Web Application" > "Register"
- Expand "OAuth 2.0 Client ID"
- Under "Web Origin" > Enter site or hostname: https://[APPENGINE_ID].appspot.com
- Create client ID. This is the Client ID for your web application, [CLIENT_ID_WEB_APPLICATION]
- Select your project in https://cloud.google.com/console/
- Select "APIs & Auth" followed by "Registered apps" (Left navigation)
- Click the "Register App" button
- Enter "Name" of the application
- Under "Platform" > Select "Web Application" > "Register"
- Expand "Certificate"
- Click "Generate Certificate"
- The email address is the Service account, [SERVICE_ACCOUNT]
- "Download private key and store it in a secure location. This is the service account private key file, [SERVICE_ACCOUNT_PRIVATE_KEY]
- Remember your private key's password.
- Generate a certificate fingerprint on your local machine.
~$ keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1
- Enter the keystore password: android
- The returned value is the CERTIFICATE_FINGERPRINT.
(stdin)= [CERTIFICATE\_FINGERPRINT]
- Select your project in https://cloud.google.com/console/
- Select "APIs & Auth" followed by "Registered apps" (Left navigation)
- Click the "Register App" button
- Enter "Name" of the application
- Under "Platform" > Select "Android" followed by "Accessing APIs directly from Android"
- Enter package name: com.google.cloud.solutions.smashpix
- Enter signing certificate fingerprint (SHA1): [CERTIFICATE_FINGERPRINT]
- Click "Register"
- Create client ID. This is the Client ID for your installed application, [CLIENT_ID_INSTALLED_APPLICATION]
- Download the Google Cloud Storage App Engine client, r65
You should have downloaded the backend server sample code. Extract the files into a new directory, [BACKEND_SERVER_CODE].
- Extract the Google Cloud Storage App Engine client dependency,
src/cloudstorage/
, folder into your backend server directory, [BACKEND_SERVER_CODE]/cloudstorage/ - In the
app.yaml
file, replace [APPENGINE_ID] with your App Engine application IDapplication: [APPENGINE\_ID]
- In the
queue.yaml
file, replace [SERVICE_ACCOUNT] with the email address of the Service accountqueue: \- name: imagetasks ... acl: [SERVICE\_ACCOUNT]
- In the
settings.cfg
file, replace the variable placeholders with your application variables- MAIN_BUCKET: Primary Google Cloud Storage bucket to upload original images
- BIT_BUCKET: Google Cloud Storage bucket to store processed images
- APP_HOSTNAME: Full App Engine hostname, [APPENGINE_ID].appspot.com
- ALLOWED_CLIENT_IDS: Client IDs that are allowed to connect to service, [CLIENT_ID_INSTALLED_APPLICATION]
- CLIENT_ID_OF_API_SERVERS: Client IDs of the Cloud Endpoints server, [CLIENT_ID_WEB_APPLICATION]
- Upload the backend server to Google App Engine
- Obtain access credentials and create configuration file using the Service account, [SERVICE_ACCOUNT]
gsutil config -e
- Create the primary bucket to upload original images, [BUCKET_TO_UPLOAD_ORIGINAL_IMAGES]
~$ gsutil mb gs://[BUCKET\_TO\_UPLOAD\_ORIGINAL\_IMAGES]
- Create the bucket to store processed images, [BUCKET_TO_STORE_PROCESSED_IMAGES]
~$ gsutil mb gs://[BUCKET\_TO\_STORE\_PROCESSED\_IMAGES]
- Configure Object Change Notification for the primary bucket to upload original images
~$ gsutil notifyconfig watchbucket https://[APPENGINE\_ID].appspot.com/ocn \ gs://[BUCKET\_TO\_UPLOAD\_ORIGINAL\_IMAGES] https://[APPENGINE\_ID].appspot.com/ocn ... Successfully created watch notification channel. Watch channel identifier: [OCN\_CHANNEL\_IDENTIFIER] Canonicalized resource identifier: [OCN\_RESOURCE\_IDENTIFIER]
- Configure the default access controls (ACL) for both buckets
~$ gsutil setdefacl public-read gs://[BUCKET\_TO\_UPLOAD\_ORIGINAL\_IMAGES] ~$ gsutil chdefacl -g AllUsers:FC gs://[BUCKET\_TO\_UPLOAD\_ORIGINAL\_IMAGES] ~$ gsutil setdefacl public-read gs://[BUCKET\_TO\_STORE\_PROCESSED\_IMAGES] ~$ gsutil chdefacl -g AllUsers:FC gs://[BUCKET\_TO\_STORE\_PROCESSED\_IMAGES]
- Note: To remove Object Change Notifications
~$ gsutil notifyconfig stopchannel [OCN_CHANNEL_IDENTIFIER] \ [OCN_RESOURCE_IDENTIFIER]
At this point, you should be able to upload images from the UI for testing purposes.
- Go to [APPENGINE_ID].appspot.com
- On the top right, "Upload a new image"
- The UI should display an image with a second image "Image processing..."
- Confirm the file upload in Google Cloud Storage
- You should also see 1 task in the App Engine console > "Task Queues" > "imagetasks"
- To process the image, we will need to setup the Command line daemon to process image in the task queue.
Configure gcutil on the main system to connect your project.
@main:~$ gcutil auth --project=[PROJECT_ID]
- Download the Google APIs Client Library for Python, 1.2
- Select "Google Compute Engine" from the main project console.
- Create a "New Instance"
- Name: smashpix-master
- Machine Type: n1-standard-1
- Boot Source: New presistent disk from image
- Use default values for all other settings.
- Go to the instance page after creation of the instance. Click "ssh" under "Equivalent REST or ssh" at the bottom of the page to obtain gcutil command line needed to SSH into the instance.
@main:~$ gcutil --service_version="v1" \ --project="[PROJECT\_ID]" ssh --zone="[INSTANCE\_ZONE]" \ "[INSTANCE\_NAME]"
- SSH into the instance to set up the Command line daemon
- Copy the command line daemon files to the instance from your main system. "." represents the root of the home directory on the Google Compute Engine instance.
@main:~$ gcutil --service_version="v1" \ --project="[PROJECT\_ID]" push --zone="[INSTANCE\_ZONE]" \ "[INSTANCE\_NAME]" daemon/ .
- Confirm that the files have been copied over
@instance:~$ ls $HOME/daemon
compute_engine_daemon.py image_processing.py quotes.txt settings.py 3. Install command line daemon dependencies
@instance:4. Copy private key over$ sudo apt-get install python-pip python-openssl$ sudo apt-get install fonts-freefont-ttf libjpeg-dev
python-dev @instance:
libpng-dev libgif-dev libtiff-dev libfreetype6-dev @instance:$ sudo ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib @instance:$ sudo ln -s /usr/lib/x86_64-linux-gnu/libpng.so /usr/lib @instance:$ sudo ln -s /usr/lib/x86_64-linux-gnu/libtiff.so /usr/lib @instance:$ sudo ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib @instance:$ sudo ln -s /usr/lib/x86_64-linux-gnu/libfreetype.so /usr/lib # libfreetype6-dev must be installed before PIL. @instance:$ sudo pip install PIL @instance:$ sudo pip install google-api-python-client @instance:$ sudo pip install gsutil
@main:~$ gcutil --service_version="v1"5. Configure settings file,
--project="[PROJECT_ID]" push --zone="[INSTANCE_ZONE]"
"smashpix-master" [SERVICE_ACCOUNT_PRIVATE_KEY] ./.ssh/.
settings.py
* PROJECT_ID: [PROJECT_ID]
* PROCESSED_IMG_BUCKET: Google Cloud Storage bucket to store processed images.
* CREDENTIAL_ACCOUNT_EMAIL: Service account email, [SERVICE_ACCOUNT_EMAIL]
* PRIVATE_KEY_LOCATION: Service account private key, [SERVICE_ACCOUNT_PRIVATE_KEY]
6. Run command line daemon
python compute_engine_daemon.py &7. Note: To add more quotes, add quotes to
quotes.txt
At this point, you should be able to view the processed image
- Go to [APPENGINE_ID].appspot.com
- The processed image should be pixelized with a quote.
- Download the Apache HttpComponents Client, 4.3.1
You should have downloaded the mobile application sample code. Extract the files into a new directory, [MOBILE_APP_CODE].
- Import the Android code into Eclipse.
- File > New > Project...
- Wizards > "Android Project from Existing Code"
- Root Directory (Select folder with the mobile application code, [MOBILE_APP_CODE])
- Projects to Import (Select project with the mobile application code)
- Extract the Apache HttpComponents Client (HttpClient) file and copy the following jar files into your Android code library folder,
[MOBILE_APP_CODE]/libs/
.httpclient-[VERSION].jar
httpclient-cache-[VERSION].jar
httpcore-[VERSION].jar
httpmime-[VERSION].jar
- Generate Google Cloud Endpoints from the backend server (Google App Engine)
- From the command line, go to the root directory of the backend server,
[BACKEND_SERVER_CODE]/
. - Create a temporary folder for the Cloud Endpoints file.
~$ mkdir endpoints-lib/
- Generate the Cloud Endpoints files for the Android application.
~$ [APPENGINE\_PYTHON\_SDK]/endpointscfg.py get\_client\_lib java -o \ endpoints-lib/. -f rest services.ImageApi
- Extract
ImageApi.zip
and save it into[BACKEND_SERVER_CODE]/endpoints-lib/image/libs/
- Copy the following jar files into your Android code library folder,
[MOBILE_APP_CODE]/libs/
.google-api-client-[VERSION].jar
google-api-client-android-[VERSION].jar
google-http-client-[VERSION].jar
google-http-client-android-[VERSION].jar
google-http-client-gson-[VERSION].jar
google-http-client-jackson-[VERSION].jar
google-http-client-jackson2-[VERSION].jar
google-oauth-client-[VERSION].jar
gson-[VERSION].jar
jackson-core-[VERSION].jar
jackson-core-asl-[VERSION].jar
jsr305-[VERSION].jar
- Extract
endpoints-lib/image/[APPENGINE_ID]-image-v[API_VERSION]-java-[VERSION]-rc-sources.jar
and copy the files into your source folder,[MOBILE_APP_CODE]/src/com/appspot/[APPENGINE_ID]/image/*
- From the command line, go to the root directory of the backend server,
- Configure the Android code to connect to the endpoints backend server
- Replace [CLIENT_ID_WEB_APPLICATION] in
[MOBILE_APP_CODE]/src/com/google/cloud/smashpix/Constants.java
- Replace [APPENGINE_ID] in
[MOBILE_APP_CODE]/src/com/google/cloud/smashpix/MainActivity.java
- Replace [APPENGINE_ID] in
[MOBILE_APP_CODE]/src/com/google/cloud/smashpix/ImageRowActivity.java
- Replace [CLIENT_ID_WEB_APPLICATION] in
- Copy the Google Play Service library
- Browse to
[ANDROID_SDK]/extras/google/google_play_services/libproject/google-play-services_lib/libs/
. - Copy
google-play-services.jar
into your Android code library folder,[MOBILE_APP_CODE]/libs/
.
- Browse to
- Make sure all code dependencies are resolved.
- Run Android application.