WallpaperCropActivity.java revision eadbfc564d84aaf1d800da3d0d6edf6312f89648
1104c45677660586026a7e74ef8c47d396403d50eMichael Jurka/* 2104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Copyright (C) 2013 The Android Open Source Project 3104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 4104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Licensed under the Apache License, Version 2.0 (the "License"); 5104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * you may not use this file except in compliance with the License. 6104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * You may obtain a copy of the License at 7104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 8104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * http://www.apache.org/licenses/LICENSE-2.0 9104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 10104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Unless required by applicable law or agreed to in writing, software 11104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * distributed under the License is distributed on an "AS IS" BASIS, 12104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * See the License for the specific language governing permissions and 14104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * limitations under the License. 15104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 16104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 17104c45677660586026a7e74ef8c47d396403d50eMichael Jurkapackage com.android.launcher3; 18104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 19104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.app.Activity; 20104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.app.WallpaperManager; 21104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.content.Context; 22104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.content.SharedPreferences; 23eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurkaimport android.content.res.Resources; 24104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.Bitmap; 25104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.Bitmap.CompressFormat; 26104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.BitmapFactory; 27104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.BitmapRegionDecoder; 28104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.Canvas; 29104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.Matrix; 30104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.Paint; 31104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.Point; 32104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.Rect; 33104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.graphics.RectF; 34104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.net.Uri; 35104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.os.AsyncTask; 36104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport android.util.Log; 37104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 38104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport com.android.gallery3d.common.Utils; 39104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 40104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.BufferedInputStream; 41104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.ByteArrayInputStream; 42104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.ByteArrayOutputStream; 43104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.FileNotFoundException; 44104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.IOException; 45104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.io.InputStream; 46104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 47104c45677660586026a7e74ef8c47d396403d50eMichael Jurka// LAUNCHER crop activity! 48104c45677660586026a7e74ef8c47d396403d50eMichael Jurkapublic class WallpaperCropActivity extends Activity { 49104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static final String LOGTAG = "Launcher3.CropActivity"; 50104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 51104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected static final String WALLPAPER_WIDTH_KEY = "wallpaper.width"; 52104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected static final String WALLPAPER_HEIGHT_KEY = "wallpaper.height"; 53104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static final int DEFAULT_COMPRESS_QUALITY = 90; 54104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 55104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The maximum bitmap size we allow to be returned through the intent. 56104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Intents have a maximum of 1MB in total size. However, the Bitmap seems to 57104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * have some overhead to hit so that we go way below the limit here to make 58104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * sure the intent stays below 1MB.We should consider just returning a byte 59104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * array instead of a Bitmap instance to avoid overhead. 60104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 61104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final int MAX_BMAP_IN_INTENT = 750000; 62104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 63104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 64104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected class BitmapCropTask extends AsyncTask<Void, Void, Boolean> { 65104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Uri mInUri = null; 66fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka int mInResId = 0; 67104c45677660586026a7e74ef8c47d396403d50eMichael Jurka InputStream mInStream; 68104c45677660586026a7e74ef8c47d396403d50eMichael Jurka RectF mCropBounds = null; 69104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int mOutWidth, mOutHeight; 70104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int mRotation = 0; // for now 71104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected final WallpaperManager mWPManager; 72104c45677660586026a7e74ef8c47d396403d50eMichael Jurka String mOutputFormat = "jpg"; // for now 73104c45677660586026a7e74ef8c47d396403d50eMichael Jurka boolean mSetWallpaper; 74104c45677660586026a7e74ef8c47d396403d50eMichael Jurka boolean mSaveCroppedBitmap; 75104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Bitmap mCroppedBitmap; 76fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka Runnable mOnEndRunnable; 77eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka Resources mResources; 78104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 79eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public BitmapCropTask(Uri inUri, 80eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka RectF cropBounds, int outWidth, int outHeight, 81fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) { 82104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mInUri = inUri; 83104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mCropBounds = cropBounds; 84104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mOutWidth = outWidth; 85104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mOutHeight = outHeight; 86104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mWPManager = WallpaperManager.getInstance(getApplicationContext()); 87104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mSetWallpaper = setWallpaper; 88104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mSaveCroppedBitmap = saveCroppedBitmap; 89fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mOnEndRunnable = onEndRunnable; 90fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka } 91fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka 92eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public BitmapCropTask(Resources res, int inResId, 93eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka RectF cropBounds, int outWidth, int outHeight, 94fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) { 95fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mInResId = inResId; 96fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mCropBounds = cropBounds; 97fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mOutWidth = outWidth; 98fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mOutHeight = outHeight; 99fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mWPManager = WallpaperManager.getInstance(getApplicationContext()); 100fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mSetWallpaper = setWallpaper; 101fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mSaveCroppedBitmap = saveCroppedBitmap; 102fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mOnEndRunnable = onEndRunnable; 103eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka mResources = res; 104104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 105104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 106104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Helper to setup input stream 107104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private void regenerateInputStream() { 108fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka if (mInUri == null && mInResId == 0) { 109fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka Log.w(LOGTAG, "cannot read original file, no input URI or resource ID given"); 110104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 111104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Utils.closeSilently(mInStream); 112104c45677660586026a7e74ef8c47d396403d50eMichael Jurka try { 113fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka if (mInUri != null) { 114fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mInStream = new BufferedInputStream( 115fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka getContentResolver().openInputStream(mInUri)); 116fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka } else { 117fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mInStream = new BufferedInputStream( 118eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka mResources.openRawResource(mInResId)); 119fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka } 120104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } catch (FileNotFoundException e) { 121104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Log.w(LOGTAG, "cannot read file: " + mInUri.toString(), e); 122104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 123104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 124104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 125104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 126104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public Point getImageBounds() { 127104c45677660586026a7e74ef8c47d396403d50eMichael Jurka regenerateInputStream(); 128104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mInStream != null) { 129104c45677660586026a7e74ef8c47d396403d50eMichael Jurka BitmapFactory.Options options = new BitmapFactory.Options(); 130104c45677660586026a7e74ef8c47d396403d50eMichael Jurka options.inJustDecodeBounds = true; 131104c45677660586026a7e74ef8c47d396403d50eMichael Jurka BitmapFactory.decodeStream(mInStream, null, options); 132104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (options.outWidth != 0 && options.outHeight != 0) { 133104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return new Point(options.outWidth, options.outHeight); 134104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 135104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 136104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return null; 137104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 138104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 139104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public void setCropBounds(RectF cropBounds) { 140104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mCropBounds = cropBounds; 141104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 142104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 143104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public Bitmap getCroppedBitmap() { 144104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mCroppedBitmap; 145104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 146104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean cropBitmap() { 147104c45677660586026a7e74ef8c47d396403d50eMichael Jurka boolean failure = false; 148104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 149104c45677660586026a7e74ef8c47d396403d50eMichael Jurka regenerateInputStream(); 150104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 151104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mInStream != null) { 152104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Find crop bounds (scaled to original image size) 153104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Rect roundedTrueCrop = new Rect(); 154104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mCropBounds.roundOut(roundedTrueCrop); 155104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 156104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (roundedTrueCrop.width() <= 0 || roundedTrueCrop.height() <= 0) { 157104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Log.w(LOGTAG, "crop has bad values for full size image"); 158104c45677660586026a7e74ef8c47d396403d50eMichael Jurka failure = true; 159104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 160104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 161104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 162104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // See how much we're reducing the size of the image 163104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int scaleDownSampleSize = Math.min(roundedTrueCrop.width() / mOutWidth, 164104c45677660586026a7e74ef8c47d396403d50eMichael Jurka roundedTrueCrop.height() / mOutHeight); 165104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 166104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Attempt to open a region decoder 167104c45677660586026a7e74ef8c47d396403d50eMichael Jurka BitmapRegionDecoder decoder = null; 168104c45677660586026a7e74ef8c47d396403d50eMichael Jurka try { 169104c45677660586026a7e74ef8c47d396403d50eMichael Jurka decoder = BitmapRegionDecoder.newInstance(mInStream, true); 170104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } catch (IOException e) { 171104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Log.w(LOGTAG, "cannot open region decoder for file: " + mInUri.toString(), e); 172104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 173104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 174104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Bitmap crop = null; 175104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (decoder != null) { 176104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Do region decoding to get crop bitmap 177104c45677660586026a7e74ef8c47d396403d50eMichael Jurka BitmapFactory.Options options = new BitmapFactory.Options(); 178104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (scaleDownSampleSize > 1) { 179104c45677660586026a7e74ef8c47d396403d50eMichael Jurka options.inSampleSize = scaleDownSampleSize; 180104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 181104c45677660586026a7e74ef8c47d396403d50eMichael Jurka crop = decoder.decodeRegion(roundedTrueCrop, options); 182104c45677660586026a7e74ef8c47d396403d50eMichael Jurka decoder.recycle(); 183104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 184104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 185104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (crop == null) { 186104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // BitmapRegionDecoder has failed, try to crop in-memory 187104c45677660586026a7e74ef8c47d396403d50eMichael Jurka regenerateInputStream(); 188104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Bitmap fullSize = null; 189104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mInStream != null) { 190104c45677660586026a7e74ef8c47d396403d50eMichael Jurka BitmapFactory.Options options = new BitmapFactory.Options(); 191104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (scaleDownSampleSize > 1) { 192104c45677660586026a7e74ef8c47d396403d50eMichael Jurka options.inSampleSize = scaleDownSampleSize; 193104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 194104c45677660586026a7e74ef8c47d396403d50eMichael Jurka fullSize = BitmapFactory.decodeStream(mInStream, null, options); 195104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 196104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (fullSize != null) { 197104c45677660586026a7e74ef8c47d396403d50eMichael Jurka crop = Bitmap.createBitmap(fullSize, roundedTrueCrop.left, 198104c45677660586026a7e74ef8c47d396403d50eMichael Jurka roundedTrueCrop.top, roundedTrueCrop.width(), 199104c45677660586026a7e74ef8c47d396403d50eMichael Jurka roundedTrueCrop.height()); 200104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 201104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 202104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 203104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (crop == null) { 204104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Log.w(LOGTAG, "cannot decode file: " + mInUri.toString()); 205104c45677660586026a7e74ef8c47d396403d50eMichael Jurka failure = true; 206104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 207104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 208fd471c0b4f028948d5aaefe37d4b9582b4b4372fMichael Jurka if (mOutWidth > 0 && mOutHeight > 0) { 209104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Matrix m = new Matrix(); 210104c45677660586026a7e74ef8c47d396403d50eMichael Jurka RectF cropRect = new RectF(0, 0, crop.getWidth(), crop.getHeight()); 211104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mRotation > 0) { 212104c45677660586026a7e74ef8c47d396403d50eMichael Jurka m.setRotate(mRotation); 213104c45677660586026a7e74ef8c47d396403d50eMichael Jurka m.mapRect(cropRect); 214104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 215fd471c0b4f028948d5aaefe37d4b9582b4b4372fMichael Jurka RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight); 216104c45677660586026a7e74ef8c47d396403d50eMichael Jurka m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL); 217104c45677660586026a7e74ef8c47d396403d50eMichael Jurka m.preRotate(mRotation); 218104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(), 219104c45677660586026a7e74ef8c47d396403d50eMichael Jurka (int) returnRect.height(), Bitmap.Config.ARGB_8888); 220104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (tmp != null) { 221104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Canvas c = new Canvas(tmp); 222104c45677660586026a7e74ef8c47d396403d50eMichael Jurka c.drawBitmap(crop, m, new Paint()); 223104c45677660586026a7e74ef8c47d396403d50eMichael Jurka crop = tmp; 224104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 225104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mRotation > 0) { 226104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Matrix m = new Matrix(); 227104c45677660586026a7e74ef8c47d396403d50eMichael Jurka m.setRotate(mRotation); 228104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Bitmap tmp = Bitmap.createBitmap(crop, 0, 0, crop.getWidth(), 229104c45677660586026a7e74ef8c47d396403d50eMichael Jurka crop.getHeight(), m, true); 230104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (tmp != null) { 231104c45677660586026a7e74ef8c47d396403d50eMichael Jurka crop = tmp; 232104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 233104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 234104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 235104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mSaveCroppedBitmap) { 236104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mCroppedBitmap = crop; 237104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 238104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 239104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Get output compression format 240104c45677660586026a7e74ef8c47d396403d50eMichael Jurka CompressFormat cf = 241104c45677660586026a7e74ef8c47d396403d50eMichael Jurka convertExtensionToCompressFormat(getFileExtension(mOutputFormat)); 242104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 243104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Compress to byte array 244104c45677660586026a7e74ef8c47d396403d50eMichael Jurka ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048); 245104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (crop.compress(cf, DEFAULT_COMPRESS_QUALITY, tmpOut)) { 246104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // If we need to set to the wallpaper, set it 247104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mSetWallpaper && mWPManager != null) { 248104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mWPManager == null) { 249104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Log.w(LOGTAG, "no wallpaper manager"); 250104c45677660586026a7e74ef8c47d396403d50eMichael Jurka failure = true; 251104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 252104c45677660586026a7e74ef8c47d396403d50eMichael Jurka try { 253104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mWPManager.setStream(new ByteArrayInputStream(tmpOut 254104c45677660586026a7e74ef8c47d396403d50eMichael Jurka .toByteArray())); 255104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } catch (IOException e) { 256104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Log.w(LOGTAG, "cannot write stream to wallpaper", e); 257104c45677660586026a7e74ef8c47d396403d50eMichael Jurka failure = true; 258104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 259104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 260104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 261fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka if (mOnEndRunnable != null) { 262fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka mOnEndRunnable.run(); 263fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka } 264104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 265104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Log.w(LOGTAG, "cannot compress bitmap"); 266104c45677660586026a7e74ef8c47d396403d50eMichael Jurka failure = true; 267104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 268104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 269104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return !failure; // True if any of the operations failed 270104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 271104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 272104c45677660586026a7e74ef8c47d396403d50eMichael Jurka @Override 273104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected Boolean doInBackground(Void... params) { 274104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return cropBitmap(); 275104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 276104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 277104c45677660586026a7e74ef8c47d396403d50eMichael Jurka @Override 278104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected void onPostExecute(Boolean result) { 279104c45677660586026a7e74ef8c47d396403d50eMichael Jurka setResult(Activity.RESULT_OK); 280104c45677660586026a7e74ef8c47d396403d50eMichael Jurka finish(); 281104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 282104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 283104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 284104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected void updateWallpaperDimensions(int width, int height) { 285104c45677660586026a7e74ef8c47d396403d50eMichael Jurka String spKey = LauncherAppState.getSharedPreferencesKey(); 286104c45677660586026a7e74ef8c47d396403d50eMichael Jurka SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_PRIVATE); 287104c45677660586026a7e74ef8c47d396403d50eMichael Jurka SharedPreferences.Editor editor = sp.edit(); 288104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (width != 0 && height != 0) { 289104c45677660586026a7e74ef8c47d396403d50eMichael Jurka editor.putInt(WALLPAPER_WIDTH_KEY, width); 290104c45677660586026a7e74ef8c47d396403d50eMichael Jurka editor.putInt(WALLPAPER_HEIGHT_KEY, height); 291104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 292104c45677660586026a7e74ef8c47d396403d50eMichael Jurka editor.remove(WALLPAPER_WIDTH_KEY); 293104c45677660586026a7e74ef8c47d396403d50eMichael Jurka editor.remove(WALLPAPER_HEIGHT_KEY); 294104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 295104c45677660586026a7e74ef8c47d396403d50eMichael Jurka editor.commit(); 296fe09cb7fe3ec1ab3e7aabd2d0415de61df31c4dbMichael Jurka 297104c45677660586026a7e74ef8c47d396403d50eMichael Jurka WallpaperPickerActivity.suggestWallpaperDimension(getResources(), 298104c45677660586026a7e74ef8c47d396403d50eMichael Jurka sp, getWindowManager(), WallpaperManager.getInstance(this)); 299104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 300104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 301104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected static CompressFormat convertExtensionToCompressFormat(String extension) { 302104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return extension.equals("png") ? CompressFormat.PNG : CompressFormat.JPEG; 303104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 304104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 305104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected static String getFileExtension(String requestFormat) { 306104c45677660586026a7e74ef8c47d396403d50eMichael Jurka String outputFormat = (requestFormat == null) 307104c45677660586026a7e74ef8c47d396403d50eMichael Jurka ? "jpg" 308104c45677660586026a7e74ef8c47d396403d50eMichael Jurka : requestFormat; 309104c45677660586026a7e74ef8c47d396403d50eMichael Jurka outputFormat = outputFormat.toLowerCase(); 310104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return (outputFormat.equals("png") || outputFormat.equals("gif")) 311104c45677660586026a7e74ef8c47d396403d50eMichael Jurka ? "png" // We don't support gif compression. 312104c45677660586026a7e74ef8c47d396403d50eMichael Jurka : "jpg"; 313104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 314104c45677660586026a7e74ef8c47d396403d50eMichael Jurka} 315