Android Impressionist Painter

Due: Friday, April 8, 11:59PM
Point Total: ~10% of your IA grade (3.5% overall)

Screenshot6.jpg

Assignment Overview
In this assignment, you will apply your growing UI programming skills to make a more sophisticated interactive prototype--an impressionist painter.
The painter works by loading in an existing image, examining some aspects of that image translated from the user's touch location (e.g., the color at pixel [x,y]), and using that to dynamic set properties in a brush. This assignment is based on Paul Baeberli's seminal 1990 SIGGRAPH paper "Paint By Numbers: Abstract Image Representations" (DOI) and by a course assignment offered in Computer Science and Engineering at the University of Washington, which I did back in 2005 but was highly influential to me! (2005 link, more recent 2014 offering).

While there are similarities between IA07 and IA08, you should start a completely new project for IA08 in Android Studio. In contrast to the last assignment, I would like you to default to a landscape orientation where the loaded image is on the left (in an ImageView) and the impressionist painting space is on the right (a custom View class, which I call ImpressionistView). In addition, please focus on designing for a tablet device (though your code/UI should also run on an Android phone). To help you get started, I have provided a skeleton project with an initial layout, some buttons, and the ImpressionistView class (link). You are welcome to change any of this as you see fit.

Similar to IA07, you will post your code to github and upload a demo of your interface to YouTube. In addition, we ask that you upload 1-3 pieces of artwork that you made with your app. Matt and I will cull these to a list of our top ~10 favorites, which the class will then vote for. Top selections will be listed on this webpage.

Required Features

  1. You must implement three brush types where a brush type is defined by having a certain shape (circles, triangles, squares) and/or behavior (paint splatter). At least one brush type must change it's behavior based on the motion of the user's finger (e.g., the brush size is dynamically set by the velocity of the finger or the brush direction is orthogonal to the user's motion). The user should be able to dynamically select the brush types and use multiple brushes on the same painting. To help inspire you to think of brush types, here are the Google Images "Impressionist Art" results.
  2. You must implement a load image feature. This is already done in the initial project code I provided.
  3. You must implement a save feature. The saved file should be automatically added to the Android photo gallery.
  4. You must implement a clear feature that clears the painting but keeps the loaded image.
  5. You must implement one bonus feature that is distinct from IA07. So, for example, if you implemented undo/redo in IA07, you cannot use this as your bonus feature in IA08 (though you can certainly program this functionality).

Potential Bonus Features

  • Use the device's camera to take a picture and load as the current ImageView, so you can quickly make impressionist artwork of your friends or other interesting things
  • To give your users more feedback, draw the location of the touch down and movement point on the ImageView. To do this, I suggest creating your own ImageView (e.g, ImpressionistImageView) that subscribes to touchdown events in the main ImpressionistView. You will have to translate the [x,y] touch locations to the ImageView.
  • Use Android's built-in physical motion sensors like the accelerometer or gyroscope to enhance your impressionist interface--for example, a brush is controlled by tilting the device
  • Read in and playback an MP3 file. As the music plays, analyze properties of the sound to dynamically change the brush (e.g., map brush size to current volume, analyze beats to control splatter, etc.)
  • When the device switches from landscape (the default) to portrait, change the layout of the app so that the paint interface takes up the full screen (or most of it) and the loaded image is shown behind it.
  • Create a particle emitter brushtype in a particle system that emits/spits out particles as your finger moves.
  • Support multi-touch so multiple fingers can simultaneously paint

Video Demo

This video demo illustrates the overall functionality of this assignment and some example brush types. The video is not comprehensive and does not include all required features (e.g., the save feature is not shown).



Learning Goals

A brief summary of this assignment's core learning goals:
  • Strengthen understanding of input events and input event listeners
  • Provide UI programming context that requires creatively thinking about efficient drawing routines and coordinating between multiple views
  • Learn more about paint objects and how to use these to create sophisticated interactive behaviors

Timeline

  • On Tuesday, April 5, you must come to class with an initial interactive prototype of your Impressionist interface and a pre-brainstormed list of potential features. At a minimum, your prototype should include one working brush that takes the pixel color from the corresponding touch location in the ImageView and draws it appropriately in the ImpressionistView. You must upload a screenshot of your app and a .zip of your code to the IA08 Android II Intermediate Deadline submission on Canvas.

  • On Friday, April 8, you will submit your deliverables via Canvas.

Record a Video

Once you're done coding, take a ~3-to-5 minute video showing off the required features plus your custom feature. Clearly explain the interface using oral narration (to save time for this assignment, you do not need to add captions--unless you want to). You can record either the emulator (use a tablet emulator) or your app running on an actual Android tablet.

Deliverables

On Canvas, you will submit a link to your YouTube video, a PDF of your favorite 1-3 pieces of artwork created with your app side-by-side with the original image, a link to the sourcecode on github, and a zip file of the source code (and requisite libraries). The github root should contain a readme that describes how to run your program and lists references to online sources that you used to build your prototype.

Rubric

You can download the rubric here (a screenshot below, which you can click to enlarge, is included for your convenience):


IA08-Android2-GradingRubric_v1c_Cropped_650w.png

Best of IA08

Like with IA07, we would like to recognize a subset of submissions as the best in class. This time, we are doing something a bit different--we are honoring not just implementations of the impressionist project but the artwork created with them. For artwork, Matt and I selected the top 12 art pieces (link). The class then voted on these using a double blind process (the voters were anonymous and the artists were also anonymous). Below, we present the top six art pieces and also recognize the best brushes and best features in the impressionist project. Congrats all!

Best Artwork

6th Place - Nazanin Assadi

6thPlace_NazaninAssadi.png

4th Place (Tie) - Nabeel Bokhari

4thPlaceTie_NabeelBokhari.png

4th Place (Tie) - Maria Mahmood

4thPlaceTie_MariaMahmood.png

3rd Place - Anumeet Nepaul

3rdPlace_AnumeetNepaul.png

2nd Place - Patrick Sweeney

2ndPlace_PatrickSweeney.png

1st Place - Patrick Sweeney

1stPlace_PatrickSweeney.png

Best Brushes

Top Overall

Patrick Sweeney

Patrick implemented a spray paint brush with animated and parameterized dripping functionality (direct link). He also implemented a soft edge gradient brush. The full video demo is below.



Runners Up


Best Features (Minus Brush Functionality)

Top Overall

Eddie Krahe

Finger location feedback with color preview (direct link), undo/redo, mode-responsive buttons. The full video is below.


Runners Up


Tips

  • For efficiency purposes, you will want to draw your brush to an offscreen bitmap and then in the ImpressionistView.onDraw method, you simply call canvas.drawBitmap(_offScreenBitmap, 0, 0, null); See skeleton code.
  • You can call "Bitmap imageViewBitmap = _imageView.getDrawingCache();" to get a copy of the ImageView as a bitmap
  • Once you have a reference to this bitmap, you can get the color for the pixel corresponding to the user's touch location in the ImpressionistView: int colorAtTouchPixelInImage = imageViewBitmap.getPixel(curPoint.x, curPoint.y); Note that this color contains R,G,B, and A values, so if you want direct control over alpha, you'll have to set this independently.

More Examples


Screenshot4.jpg
Screenshot_2016-03-23-23-15-58.jpg

Screenshot8.jpg

Screenshot9.jpg
Screenshot_2016-03-23-22-50-36.jpg

Screenshot_2016-03-23-23-03-18.jpg