Java tutorial
/* * Copyright (C) 2007 The Android Open Source Project * * 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. */ package jp.envision.android.cloudfingerpaint; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.util.Date; import org.apache.http.client.methods.HttpPost; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.graphics.*; import android.location.Location; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.text.format.DateFormat; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.ByteArrayBody; import org.apache.http.impl.client.DefaultHttpClient; public class CloudFingerPaint extends GraphicsActivity implements ColorPickerDialog.OnColorChangedListener { public MyView myView; private static final String TAG = "CloudFingerPaint"; private static final String APPLICATION_NAME = "CloudFingerPaint"; private static final String PATH = Environment.getExternalStorageDirectory().toString() + "/" + APPLICATION_NAME; private ProgressDialog progressDialog; private AlertDialog.Builder alertDialogBuilder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); myView = new MyView(this); setContentView(myView); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); //mPaint.setColor(0xFFFF0000); mPaint.setColor(0xFF000000); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(5); mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f); mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL); alertDialogBuilder = new AlertDialog.Builder(this); } private Paint mPaint; private MaskFilter mEmboss; private MaskFilter mBlur; public void colorChanged(int color) { mPaint.setColor(color); } public class MyView extends View { private static final float MINP = 0.25f; private static final float MAXP = 0.75f; private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mBitmapPaint; public MyView(Context c) { super(c); mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); mCanvas.drawColor(Color.WHITE); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFAAAAAA); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); canvas.drawPath(mPath, mPaint); } private float mX, mY; private static final float TOUCH_TOLERANCE = 4; private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; } } private void touch_up() { mPath.lineTo(mX, mY); // commit the path to our offscreen mCanvas.drawPath(mPath, mPaint); // kill this so we don't double draw mPath.reset(); } private void clear_all() { mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); mCanvas.drawColor(Color.WHITE); invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } } private static final int COLOR_MENU_ID = Menu.FIRST; private static final int EMBOSS_MENU_ID = Menu.FIRST + 1; private static final int BLUR_MENU_ID = Menu.FIRST + 2; private static final int ERASE_MENU_ID = Menu.FIRST + 3; private static final int SRCATOP_MENU_ID = Menu.FIRST + 4; private static final int PRINT_MENU_ID = Menu.FIRST + 5; private static final int CLEAR_MENU_ID = Menu.FIRST + 6; @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); //menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c'); menu.add(0, PRINT_MENU_ID, 0, "Print").setShortcut('3', 's'); menu.add(0, CLEAR_MENU_ID, 0, "Clear").setShortcut('3', 'c'); /* menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's'); menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z'); menu.add(0, ERASE_MENU_ID, 0, "Erase").setShortcut('5', 'z'); menu.add(0, SRCATOP_MENU_ID, 0, "SrcATop").setShortcut('5', 'z'); */ return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { mPaint.setXfermode(null); mPaint.setAlpha(0xFF); switch (item.getItemId()) { case COLOR_MENU_ID: new ColorPickerDialog(this, this, mPaint.getColor()).show(); return true; case PRINT_MENU_ID: progressDialog = new ProgressDialog(this); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.setMessage("???s..."); progressDialog.setCancelable(true); progressDialog.show(); (new Thread(runnable)).start(); return true; case EMBOSS_MENU_ID: if (mPaint.getMaskFilter() != mEmboss) { mPaint.setMaskFilter(mEmboss); } else { mPaint.setMaskFilter(null); } return true; case BLUR_MENU_ID: if (mPaint.getMaskFilter() != mBlur) { mPaint.setMaskFilter(mBlur); } else { mPaint.setMaskFilter(null); } return true; case ERASE_MENU_ID: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); return true; case SRCATOP_MENU_ID: mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); mPaint.setAlpha(0x80); return true; case CLEAR_MENU_ID: Log.d(TAG, "Clear canvas."); myView.clear_all(); return true; } return super.onOptionsItemSelected(item); } private Runnable runnable = new Runnable() { public void run() { try { String directory = PATH; File dir = new File(directory); if (!dir.exists()) { dir.mkdirs(); Log.d(TAG, dir.toString() + " create"); } String filename = DateFormat.format("yyyy-MM-dd_hh-mm-ss", new java.util.Date()) + ".png"; Log.d(TAG, "filename: " + filename); File file = new File(directory, filename); OutputStream output = new FileOutputStream(file); Bitmap b = Bitmap.createScaledBitmap(myView.mBitmap, 320, 480, false); //FileOutputStream output = openFileOutput(dst, Context.MODE_WORLD_READABLE); b.compress(Bitmap.CompressFormat.PNG, 100, output); ByteArrayOutputStream bos = new ByteArrayOutputStream(); b.compress(Bitmap.CompressFormat.PNG, 100, bos); byte[] data = bos.toByteArray(); HttpClient httpClient = new DefaultHttpClient(); HttpPost postRequest = new HttpPost("http://cloud-finger-paint.appspot.com/api/upload"); ByteArrayBody bab = new ByteArrayBody(data, "screen.png"); MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); reqEntity.addPart("image", bab); postRequest.setEntity(reqEntity); HttpResponse response = httpClient.execute(postRequest); BufferedReader reader = new BufferedReader( new InputStreamReader(response.getEntity().getContent(), "UTF-8")); String sResponse; StringBuilder s = new StringBuilder(); while ((sResponse = reader.readLine()) != null) { s = s.append(sResponse); } Log.d(TAG, "Response: " + s); Message message = new Message(); Bundle bundle = new Bundle(); bundle.putString("msg", "?L?[o^?B"); message.setData(bundle); handler.sendMessage(message); } catch (Throwable e) { Message message = new Message(); Bundle bundle = new Bundle(); bundle.putString("msg", "?L?[o^s?B"); message.setData(bundle); handler.sendMessage(message); e.printStackTrace(); } progressDialog.dismiss(); } }; private final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { String text = msg.getData().get("msg").toString(); alertDialogBuilder.setTitle("Cloud Finger Paint"); alertDialogBuilder.setMessage(text); alertDialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } }); alertDialogBuilder.setCancelable(true); AlertDialog alertDialog = alertDialogBuilder.create(); alertDialog.show(); } }; }