/** * Copyright © 2011,2013 Konstantin Livitski * * This file is part of n-Puzzle application. n-Puzzle application is free * software; you can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * n-Puzzle application contains adaptations of artwork covered by the Creative * Commons Attribution-ShareAlike 3.0 Unported license. Please refer to the * NOTICE.md file at the root of this distribution or repository for licensing * terms that apply to that artwork. * * n-Puzzle application is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * n-Puzzle application; if not, see the LICENSE/gpl.txt file of this distribution * or visit <http://www.gnu.org/licenses>. */ package name.livitski.games.puzzle.android; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Handler; import android.os.Message; /** * Reads an image into a bitmap, downscales it to the * {@link #setMaxFrameDimension(int) frame dimension}, * and sends the parent a {@link Message} containing this * object. This class is designed to run as a background task. */ public class ImageConverter implements Runnable { @Override public void run() { InputStream pictureData = null; try { BitmapFactory.Options bitmapInfo = prepareOptions(); pictureData = openInputStream(); bitmap = BitmapFactory.decodeStream(pictureData, null, bitmapInfo); } catch (Throwable failure) { status = failure; } finally { if (null != pictureData) try { pictureData.close(); } catch (Exception ignored) {} notifyParent(); } } protected void notifyParent() { if (null == message) message = new Message(); message.obj = this; parentHandler.sendMessage(message); } protected BitmapFactory.Options prepareOptions() throws IOException { InputStream pictureData = null; try { pictureData = openInputStream(); BitmapFactory.Options bitmapInfo = new BitmapFactory.Options(); bitmapInfo.inJustDecodeBounds = true; BitmapFactory.decodeStream(pictureData, null, bitmapInfo); pictureData.close(); pictureData = null; int maxBitmapSize = bitmapInfo.outWidth; if (maxBitmapSize < bitmapInfo.outHeight) maxBitmapSize = bitmapInfo.outHeight; if (maxBitmapSize > maxFrameDim && (0 > maxFrameDim * 2 || maxBitmapSize >= maxFrameDim * 2)) { bitmapInfo.inJustDecodeBounds = false; bitmapInfo.inSampleSize = (maxBitmapSize - 1) / maxFrameDim + 1; return bitmapInfo; } else return null; } finally { if (null != pictureData) try { pictureData.close(); } catch (Exception ignored) {} } } protected InputStream openInputStream() throws FileNotFoundException { if (null != imageURI) return context.getContentResolver().openInputStream(imageURI); else return context.getResources().openRawResource(imageResource); } public Throwable getStatus() { return status; } public Bitmap getBitmap() { return bitmap; } public void setMaxFrameDimension(int dim) { this.maxFrameDim = dim; } public Uri getImageURI() { return imageURI; } public void setImageURI(Uri imageURI) { this.imageURI = imageURI; this.imageResource = 0; } public void setImageId(Serializable imageId) { if (imageId instanceof Integer) { this.imageResource = (Integer)imageId; this.imageURI = null; } else setImageURI(Uri.fromFile(ImageSource.imageFileForId((String)imageId, context))); } /** * Stores a predefined message to be sent with the notification. * Note that the {@link Message#obj} property of the argument will * be replaced with this object's reference. * @param message predefined message object */ public void setMessage(Message message) { this.message = message; } public ImageConverter(final Context context, final Handler handler) { this.parentHandler = handler; this.context = context; } protected void setStatus(Throwable status) { this.status = status; } protected Handler getParentHandler() { return parentHandler; } private Context context; private Handler parentHandler; private Throwable status; private Uri imageURI; private int imageResource; private int maxFrameDim; private Bitmap bitmap; private Message message; }