Updated the Android Test app to use a wider viewfinder, to save images as PNGs instea...
[zxing.git] / androidtest / src / com / google / zxing / client / androidtest / SaveThread.java
1 /*
2  * Copyright (C) 2008 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.client.androidtest;
18
19 import android.graphics.Bitmap;
20 import android.graphics.Rect;
21 import android.os.Handler;
22 import android.os.Looper;
23 import android.os.Message;
24 import android.util.Log;
25
26 import java.io.File;
27 import java.io.FileNotFoundException;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.OutputStream;
31 import java.util.Date;
32
33 final class SaveThread extends Thread {
34
35   private static final String TAG = "SaveThread";
36
37   public Handler mHandler;
38
39   private final CameraTestActivity mActivity;
40   private final Rect mFramingRect;
41
42   SaveThread(CameraTestActivity activity, Rect framingRect) {
43     mActivity = activity;
44     mFramingRect = framingRect;
45   }
46
47   @Override
48   public void run() {
49     Looper.prepare();
50     mHandler = new Handler() {
51       @Override
52       public void handleMessage(Message message) {
53         switch (message.what) {
54           case R.id.save:
55             save((byte[]) message.obj, message.arg1, message.arg2);
56             break;
57           case R.id.quit:
58             Looper.myLooper().quit();
59             break;
60         }
61       }
62     };
63     Looper.loop();
64   }
65
66   // Save the center rectangle of the Y channel as a greyscale PNG to the SD card.
67   private void save(byte[] data, int width, int height) {
68     int framingWidth = mFramingRect.width();
69     int framingHeight = mFramingRect.height();
70     if (framingWidth > width || framingHeight > height) {
71       throw new IllegalArgumentException();
72     }
73
74     int leftOffset = mFramingRect.left;
75     int topOffset = mFramingRect.top;
76     int[] colors = new int[framingWidth * framingHeight];
77
78     for (int y = 0; y < framingHeight; y++) {
79       int rowOffset = (y + topOffset) * width + leftOffset;
80       for (int x = 0; x < framingWidth; x++) {
81         int pixel = (int) data[rowOffset + x];
82         pixel = 0xff000000 + (pixel << 16) + (pixel << 8) + pixel;
83         colors[y * framingWidth + x] = pixel;
84       }
85     }
86
87     Bitmap bitmap = Bitmap.createBitmap(colors, framingWidth, framingHeight,
88         Bitmap.Config.ARGB_8888);
89     OutputStream outStream = getNewPhotoOutputStream();
90     if (outStream != null) {
91       bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
92       try {
93         outStream.close();
94         Message message = Message.obtain(mActivity.mHandler, R.id.save_succeeded);
95         message.sendToTarget();
96         return;
97       } catch (IOException e) {
98         Log.e(TAG, "Exception closing stream: " + e.toString());
99       }
100     }
101
102     Message message = Message.obtain(mActivity.mHandler, R.id.save_failed);
103     message.sendToTarget();
104   }
105
106   private static OutputStream getNewPhotoOutputStream() {
107     File sdcard = new File("/sdcard");
108     if (sdcard.exists()) {
109       File barcodes = new File(sdcard, "barcodes");
110       if (barcodes.exists()) {
111         if (!barcodes.isDirectory()) {
112           Log.e(TAG, "/sdcard/barcodes exists but is not a directory");
113           return null;
114         }
115       } else {
116         if (!barcodes.mkdir()) {
117           Log.e(TAG, "Could not create /sdcard/barcodes directory");
118           return null;
119         }
120       }
121       Date now = new Date();
122       String fileName = now.getTime() + ".png";
123       try {
124         return new FileOutputStream(new File(barcodes, fileName));
125       } catch (FileNotFoundException e) {
126         Log.e(TAG, "Could not create FileOutputStream");
127       }
128     } else {
129       Log.e(TAG, "/sdcard does not exist");
130     }
131     return null;
132   }
133
134 }