Last active
August 29, 2015 14:04
-
-
Save kamikat/fc526be4a24abab0c6eb to your computer and use it in GitHub Desktop.
RoboSpice image thumbnail request handling EXIF data of input file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.graphics.Bitmap; | |
import android.graphics.BitmapFactory; | |
import android.graphics.Canvas; | |
import android.graphics.Color; | |
import android.graphics.Matrix; | |
import android.graphics.Paint; | |
import android.graphics.RectF; | |
import android.media.ExifInterface; | |
import java.io.File; | |
public class ImageThumbnailRequest extends ThumbnailRequest { | |
BitmapFactory.Options mOptions; | |
public ImageThumbnailRequest(File file) { | |
this(file, SIZE_AUTO, SIZE_AUTO); | |
} | |
public ImageThumbnailRequest(File file, int width, int height) { | |
super(file, width, height); | |
} | |
public Bitmap loadDataFromNetwork() throws Exception { | |
mOptions = new BitmapFactory.Options(); | |
mOptions.inJustDecodeBounds = true; | |
BitmapFactory.decodeFile(getFile().getAbsolutePath(), mOptions); | |
mOptions.inJustDecodeBounds = false; | |
// obtain EXIF transformation matrix from file | |
ExifInterface exif = new ExifInterface(getFile().getAbsolutePath()); | |
Matrix matxif = getExifTransformMatrix(exif); | |
// get dimension of source bitmap and transform dimension with EXIF information | |
float[] dimen = { mOptions.outWidth, mOptions.outHeight }; | |
matxif.mapPoints(dimen); | |
mOptions.inSampleSize = calculateInSampleSize(Math.abs(dimen[0]), Math.abs(dimen[1])); | |
// decode thumbnail bitmap file into memory | |
Bitmap bmp = BitmapFactory.decodeFile(getFile().getAbsolutePath(), mOptions); | |
RectF srcRect = new RectF(0, 0, bmp.getWidth(), bmp.getHeight()); | |
RectF dstRect = new RectF(); | |
matxif.mapRect(dstRect, srcRect); | |
// create a new bitmap to draw thumbnail with EXIF transformed | |
Bitmap decorated = Bitmap.createBitmap( | |
Math.round(dstRect.width()), | |
Math.round(dstRect.height()), | |
Bitmap.Config.ARGB_8888); | |
Canvas canvas = new Canvas(decorated); | |
// pre-processing | |
preDraw(canvas); | |
// relocate anchor for the canvas | |
canvas.translate(-dstRect.left, -dstRect.top); | |
canvas.concat(matxif); | |
// draw thumbnail bitmap | |
canvas.drawBitmap(bmp, null, srcRect, new Paint() {{ | |
setAntiAlias(true); | |
setFilterBitmap(false); | |
setDither(false); | |
}}); | |
// clear matrix | |
canvas.setMatrix(null); | |
// post-processing | |
postDraw(canvas); | |
// should better gc now | |
canvas.setBitmap(null); | |
System.gc(); | |
return decorated; | |
} | |
/** | |
* draw background on to thumbnail canvas (white background by default for JPEG bitmap thumbnail caching) | |
* @param canvas | |
*/ | |
public void preDraw(Canvas canvas) { | |
canvas.drawColor(Color.WHITE); | |
} | |
/** | |
* draw objects overlaid on source image (default none) | |
* @param canvas | |
*/ | |
public void postDraw(Canvas canvas) { } | |
/** | |
* use this interface to configure bitmap decode parameters | |
* the class will take care of inSampleSize and inJustDecodeBound by itself, | |
* so put other settings here. | |
* | |
* @param options | |
* options passed to BitmapFactory.decodeFile | |
*/ | |
public void setDecodeOptions(BitmapFactory.Options options) { | |
mOptions = options; | |
} | |
private Matrix getExifTransformMatrix(ExifInterface exif) { | |
Matrix matrix = new Matrix(); | |
switch(exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)) { | |
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: | |
matrix.postScale(-1, 1); | |
break; | |
case ExifInterface.ORIENTATION_ROTATE_180: | |
matrix.postRotate(180); | |
break; | |
case ExifInterface.ORIENTATION_FLIP_VERTICAL: | |
matrix.postScale(1, -1); | |
break; | |
case ExifInterface.ORIENTATION_TRANSPOSE: | |
matrix.postRotate(90); | |
matrix.postScale(-1, 1); | |
break; | |
case ExifInterface.ORIENTATION_ROTATE_90: | |
matrix.postRotate(90); | |
break; | |
case ExifInterface.ORIENTATION_TRANSVERSE: | |
matrix.postScale(-1, -1); | |
break; | |
case ExifInterface.ORIENTATION_ROTATE_270: | |
matrix.postRotate(270); | |
break; | |
} | |
return matrix; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.graphics.Bitmap; | |
import com.octo.android.robospice.request.SpiceRequest; | |
import java.io.File; | |
public abstract class ThumbnailRequest extends SpiceRequest<Bitmap> { | |
public static final int SIZE_AUTO = -1; | |
protected File mFile; | |
protected int mWidth; | |
protected int mHeight; | |
public ThumbnailRequest(File file) { | |
this(file, SIZE_AUTO, SIZE_AUTO); | |
} | |
public ThumbnailRequest(File file, int width, int height) { | |
super(Bitmap.class); | |
mFile = file; | |
mWidth = width; | |
mHeight = height; | |
} | |
public File getFile() { | |
return mFile; | |
} | |
protected int calculateInSampleSize(float width, float height) { | |
if (height > mHeight || width > mWidth) { | |
if ( mWidth == -1 && mHeight == -1) { | |
return 1; | |
} | |
if (mWidth == -1) { | |
return Math.round(height / (float) mHeight); | |
} | |
if (mHeight == -1) { | |
return Math.round(width / (float) mWidth); | |
} | |
if (width < height) { | |
return Math.round(width / (float) mWidth); | |
} else { | |
return Math.round(height / (float) mHeight); | |
} | |
} else { | |
return 1; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment