Fix 5156702: rotate thumbnails

Change-Id: I97b51dadf129172d5b154e9dfd66da254e4559d7
This commit is contained in:
Chih-Chung Chang
2011-09-07 19:20:45 +08:00
parent 7a57009c3a
commit 47a52158d2
5 changed files with 87 additions and 118 deletions

View File

@@ -3758,65 +3758,33 @@ class MediaArtistNativeHelper {
/**
* This method extracts a frame from the input file
* and returns the frame as a bitmap
*
* @param inputFile The inputFile
* @param width The width of the output frame
* @param height The height of the output frame
* @param timeMS The time in ms at which the frame has to be extracted
* and returns the frame as a bitmap. See getPixelsList() for more information.
*/
Bitmap getPixels(String inputFile, int width, int height, long timeMS) {
if (inputFile == null) {
throw new IllegalArgumentException("Invalid input file");
}
/* Make width and height as even */
final int newWidth = (width + 1) & 0xFFFFFFFE;
final int newHeight = (height + 1) & 0xFFFFFFFE;
/* Create a temp bitmap for resized thumbnails */
Bitmap tempBitmap = null;
if ((newWidth != width) || (newHeight != height)) {
tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
}
IntBuffer rgb888 = IntBuffer.allocate(newWidth * newHeight * 4);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
nativeGetPixels(inputFile, rgb888.array(), newWidth, newHeight, timeMS);
if ((newWidth == width) && (newHeight == height)) {
bitmap.copyPixelsFromBuffer(rgb888);
} else {
/* Create a temp bitmap to be used for resize */
tempBitmap.copyPixelsFromBuffer(rgb888);
/* Create a canvas to resize */
final Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
new Rect(0, 0, width, height), sResizePaint);
canvas.setBitmap(null);
}
if (tempBitmap != null) {
tempBitmap.recycle();
}
return bitmap;
Bitmap getPixels(String filename, int width, int height, long timeMs,
int videoRotation) {
final Bitmap result[] = new Bitmap[1];
getPixelsList(filename, width, height, timeMs, timeMs, 1, new int[] {0},
new MediaItem.GetThumbnailListCallback() {
public void onThumbnail(Bitmap bitmap, int index) {
result[0] = bitmap;
}
}, videoRotation);
return result[0];
}
/**
* This method extracts a list of frame from the
* input file and returns the frame in bitmap array
*
* @param filename The inputFile
* @param width The width of the output frame
* @param height The height of the output frame
* @param filename The input file name
* @param width The width of the output frame, before rotation
* @param height The height of the output frame, before rotation
* @param startMs The starting time in ms
* @param endMs The end time in ms
* @param thumbnailCount The number of frames to be extracted
* @param indices The indices of thumbnails wanted
* @param callback The callback used to pass back the bitmaps
* from startMs to endMs
* @param videoRotation The rotation degree need to be done for the bitmap
*
* @return The frames as bitmaps in bitmap array
**/
@@ -3824,62 +3792,69 @@ class MediaArtistNativeHelper {
long startMs, long endMs, int thumbnailCount, int[] indices,
final MediaItem.GetThumbnailListCallback callback,
final int videoRotation) {
/* Make width and height as even */
final int newWidth = (width + 1) & 0xFFFFFFFE;
final int newHeight = (height + 1) & 0xFFFFFFFE;
final int thumbnailSize = newWidth * newHeight;
/* Create a temp bitmap for resized thumbnails */
final Bitmap tempBitmap =
(newWidth != width || newHeight != height)
? Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888)
// The decoder needs output width and height as even
final int decWidth = (width + 1) & 0xFFFFFFFE;
final int decHeight = (height + 1) & 0xFFFFFFFE;
final int thumbnailSize = decWidth * decHeight;
// We convert the decoder output (in int[]) to a bitmap by first
// copy it into an IntBuffer, then use Bitmap.copyPixelsFromBuffer to
// copy it to the bitmap.
final int[] decArray = new int[thumbnailSize];
final IntBuffer decBuffer = IntBuffer.allocate(thumbnailSize);
// If we need to resize and/or rotate the decoder output, we need a
// temporary bitmap to hold the decoded output.
final boolean needToMassage =
(decWidth != width || decHeight != height || videoRotation != 0);
final Bitmap tmpBitmap = needToMassage
? Bitmap.createBitmap(decWidth, decHeight, Bitmap.Config.ARGB_8888)
: null;
final int[] rgb888 = new int[thumbnailSize];
final IntBuffer tmpBuffer = IntBuffer.allocate(thumbnailSize);
nativeGetPixelsList(filename, rgb888, newWidth, newHeight,
thumbnailCount, videoRotation, startMs, endMs, indices,
// The final output bitmap width/height may swap because of rotation.
final boolean needToSwapWH = (videoRotation == 90 || videoRotation == 270);
final int outWidth = needToSwapWH ? height : width;
final int outHeight = needToSwapWH ? width : height;
nativeGetPixelsList(filename, decArray, decWidth, decHeight,
thumbnailCount, startMs, endMs, indices,
new NativeGetPixelsListCallback() {
public void onThumbnail(int index) {
Bitmap bitmap = Bitmap.createBitmap(
width, height, Bitmap.Config.ARGB_8888);
tmpBuffer.put(rgb888, 0, thumbnailSize);
tmpBuffer.rewind();
// This is the bitmap we will output to the client
Bitmap outBitmap = Bitmap.createBitmap(
outWidth, outHeight, Bitmap.Config.ARGB_8888);
if ((newWidth == width) && (newHeight == height)) {
bitmap.copyPixelsFromBuffer(tmpBuffer);
// Copy int[] to IntBuffer
decBuffer.put(decArray, 0, thumbnailSize);
decBuffer.rewind();
if (!needToMassage) {
// We can directly read the decoded result to output bitmap
outBitmap.copyPixelsFromBuffer(decBuffer);
} else {
/* Copy the out rgb buffer to temp bitmap */
tempBitmap.copyPixelsFromBuffer(tmpBuffer);
// Copy the decoded result to an intermediate bitmap first
tmpBitmap.copyPixelsFromBuffer(decBuffer);
/* Create a canvas to resize */
final Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(tempBitmap,
new Rect(0, 0, newWidth, newHeight),
new Rect(0, 0, width, height), sResizePaint);
canvas.setBitmap(null);
// Create a canvas to resize/rotate the bitmap
// First scale the decoded bitmap to (0,0)-(1,1), rotate it
// with (0.5, 0.5) as center, then scale it to
// (outWidth, outHeight).
final Canvas canvas = new Canvas(outBitmap);
Matrix m = new Matrix();
float sx = 1f / decWidth;
float sy = 1f / decHeight;
m.postScale(sx, sy);
m.postRotate(videoRotation, 0.5f, 0.5f);
m.postScale(outWidth, outHeight);
canvas.drawBitmap(tmpBitmap, m, sResizePaint);
}
if (videoRotation == 0) {
callback.onThumbnail(bitmap, index);
} else {
Matrix mtx = new Matrix();
mtx.postRotate(videoRotation);
Bitmap rotatedBmp =
Bitmap.createBitmap(bitmap, 0, 0, width, height, mtx, false);
callback.onThumbnail(rotatedBmp, index);
if (bitmap != null) {
bitmap.recycle();
}
}
callback.onThumbnail(outBitmap, index);
}
});
if (tempBitmap != null) {
tempBitmap.recycle();
if (tmpBitmap != null) {
tmpBitmap.recycle();
}
}
@@ -3996,7 +3971,7 @@ class MediaArtistNativeHelper {
long timeMS);
private native int nativeGetPixelsList(String fileName, int[] pixelArray,
int width, int height, int nosofTN, int videoRotation, long startTimeMs,
int width, int height, int nosofTN, long startTimeMs,
long endTimeMs, int[] indices, NativeGetPixelsListCallback callback);
/**

View File

@@ -606,7 +606,7 @@ public class MediaImageItem extends MediaItem {
public Bitmap getThumbnail(int width, int height, long timeMs) throws IOException {
if (getGeneratedImageClip() != null) {
return mMANativeHelper.getPixels(getGeneratedImageClip(),
width, height,timeMs);
width, height, timeMs, 0);
} else {
return scaleImage(mFilename, width, height);
}

View File

@@ -293,7 +293,14 @@ public class MediaVideoItem extends MediaItem {
throw new IllegalArgumentException("Invalid Dimensions");
}
return mMANativeHelper.getPixels(super.getFilename(), width, height,timeMs);
if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
int temp = width;
width = height;
height = temp;
}
return mMANativeHelper.getPixels(
getFilename(), width, height, timeMs, mVideoRotationDegree);
}
/*
@@ -318,8 +325,14 @@ public class MediaVideoItem extends MediaItem {
throw new IllegalArgumentException("Invalid dimension");
}
mMANativeHelper.getPixelsList(super.getFilename(), width,
height, startMs, endMs, thumbnailCount, indices, callback,
if (mVideoRotationDegree == 90 || mVideoRotationDegree == 270) {
int temp = width;
width = height;
height = temp;
}
mMANativeHelper.getPixelsList(getFilename(), width, height,
startMs, endMs, thumbnailCount, indices, callback,
mVideoRotationDegree);
}

View File

@@ -1825,27 +1825,10 @@ public class VideoEditorImpl implements VideoEditor {
if (mMediaItems.size() > 0) {
MediaItem mI = mMediaItems.get(0);
/*
* Lets initialize the width for default aspect ratio i.e 16:9
* Keep aspect ratio of the image
*/
int height = 480;
int width = 854;
switch (mI.getAspectRatio()) {
case MediaProperties.ASPECT_RATIO_3_2:
width = 720;
break;
case MediaProperties.ASPECT_RATIO_4_3:
width = 640;
break;
case MediaProperties.ASPECT_RATIO_5_3:
width = 800;
break;
case MediaProperties.ASPECT_RATIO_11_9:
width = 586;
break;
case MediaProperties.ASPECT_RATIO_16_9:
case MediaProperties.ASPECT_RATIO_UNDEFINED:
break;
}
int width = mI.getWidth() * height / mI.getHeight();
Bitmap projectBitmap = null;
String filename = mI.getFilename();

View File

@@ -185,7 +185,6 @@ static int videoEditor_getPixelsList(
M4OSA_UInt32 width,
M4OSA_UInt32 height,
M4OSA_UInt32 noOfThumbnails,
M4OSA_UInt32 videoRotation,
jlong startTime,
jlong endTime,
jintArray indexArray,
@@ -292,7 +291,7 @@ static JNINativeMethod gManualEditMethods[] = {
(void *)videoEditor_release },
{"nativeGetPixels", "(Ljava/lang/String;[IIIJ)I",
(void*)videoEditor_getPixels },
{"nativeGetPixelsList", "(Ljava/lang/String;[IIIIIJJ[ILandroid/media/videoeditor/MediaArtistNativeHelper$NativeGetPixelsListCallback;)I",
{"nativeGetPixelsList", "(Ljava/lang/String;[IIIIJJ[ILandroid/media/videoeditor/MediaArtistNativeHelper$NativeGetPixelsListCallback;)I",
(void*)videoEditor_getPixelsList },
{"getMediaProperties",
"(Ljava/lang/String;)Landroid/media/videoeditor/MediaArtistNativeHelper$Properties;",
@@ -2286,7 +2285,6 @@ static int videoEditor_getPixelsList(
M4OSA_UInt32 width,
M4OSA_UInt32 height,
M4OSA_UInt32 noOfThumbnails,
M4OSA_UInt32 videoRotation,
jlong startTime,
jlong endTime,
jintArray indexArray,