Files
frameworks_base/media/java/android/media/videoeditor/MediaImageItem.java
Gil Dobjanschi 53f89e1230 Added the video editor to the media items and audio track constructors.
Change-Id: I5db229d28c28e17b487257a9c4ed8c5fb7570a8d
2010-10-06 09:54:34 -07:00

263 lines
8.4 KiB
Java
Executable File

/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.media.videoeditor;
import java.io.IOException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.util.Pair;
/**
* This class represents an image item on the storyboard. Note that images are
* scaled down to the maximum supported resolution by preserving the native
* aspect ratio. To learn the scaled image dimensions use
* {@link #getScaledWidth()} and {@link #getScaledHeight()} respectively.
*
* {@hide}
*/
public class MediaImageItem extends MediaItem {
// Logging
private static final String TAG = "MediaImageItem";
// The resize paint
private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
// Instance variables
private final int mWidth;
private final int mHeight;
private final int mAspectRatio;
private long mDurationMs;
private int mScaledWidth, mScaledHeight;
/**
* This class cannot be instantiated by using the default constructor
*/
@SuppressWarnings("unused")
private MediaImageItem() throws IOException {
this(null, null, null, 0, RENDERING_MODE_BLACK_BORDER);
}
/**
* Constructor
*
* @param editor The video editor reference
* @param mediaItemId The media item id
* @param filename The image file name
* @param durationMs The duration of the image on the storyboard
* @param renderingMode The rendering mode
*
* @throws IOException
*/
public MediaImageItem(VideoEditor editor, String mediaItemId, String filename, long durationMs,
int renderingMode)
throws IOException {
super(editor, mediaItemId, filename, renderingMode);
// Determine the dimensions of the image
final BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, dbo);
mWidth = dbo.outWidth;
mHeight = dbo.outHeight;
mDurationMs = durationMs;
// TODO: Determine the aspect ratio from the width and height
mAspectRatio = MediaProperties.ASPECT_RATIO_4_3;
// Images are stored in memory scaled to the maximum resolution to
// save memory.
final Pair<Integer, Integer>[] resolutions =
MediaProperties.getSupportedResolutions(mAspectRatio);
// Get the highest resolution
final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1];
if (mHeight > maxResolution.second) {
// We need to scale the image
scaleImage(filename, maxResolution.first, maxResolution.second);
mScaledWidth = maxResolution.first;
mScaledHeight = maxResolution.second;
} else {
mScaledWidth = mWidth;
mScaledHeight = mHeight;
}
}
/*
* {@inheritDoc}
*/
@Override
public int getFileType() {
if (mFilename.endsWith(".jpg") || mFilename.endsWith(".jpeg")) {
return MediaProperties.FILE_JPEG;
} else if (mFilename.endsWith(".png")) {
return MediaProperties.FILE_PNG;
} else {
return MediaProperties.FILE_UNSUPPORTED;
}
}
/*
* {@inheritDoc}
*/
@Override
public int getWidth() {
return mWidth;
}
/*
* {@inheritDoc}
*/
@Override
public int getHeight() {
return mHeight;
}
/**
* @return The scaled width of the image.
*/
public int getScaledWidth() {
return mScaledWidth;
}
/**
* @return The scaled height of the image.
*/
public int getScaledHeight() {
return mScaledHeight;
}
/*
* {@inheritDoc}
*/
@Override
public int getAspectRatio() {
return mAspectRatio;
}
/**
* This method will adjust the duration of bounding transitions, effects
* and overlays if the current duration of the transactions become greater
* than the maximum allowable duration.
*
* @param durationMs The duration of the image in the storyboard timeline
*/
public void setDuration(long durationMs) {
mDurationMs = durationMs;
adjustElementsDuration();
}
/*
* {@inheritDoc}
*/
@Override
public long getTimelineDuration() {
return mDurationMs;
}
/*
* {@inheritDoc}
*/
@Override
public Bitmap getThumbnail(int width, int height, long timeMs) throws IOException {
return scaleImage(mFilename, width, height);
}
/*
* {@inheritDoc}
*/
@Override
public Bitmap[] getThumbnailList(int width, int height, long startMs, long endMs,
int thumbnailCount) throws IOException {
final Bitmap thumbnail = scaleImage(mFilename, width, height);
final Bitmap[] thumbnailArray = new Bitmap[thumbnailCount];
for (int i = 0; i < thumbnailCount; i++) {
thumbnailArray[i] = thumbnail;
}
return thumbnailArray;
}
/**
* Resize a bitmap to the specified width and height
*
* @param filename The filename
* @param width The thumbnail width
* @param height The thumbnail height
*
* @return The resized bitmap
*/
private Bitmap scaleImage(String filename, int width, int height)
throws IOException {
final BitmapFactory.Options dbo = new BitmapFactory.Options();
dbo.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, dbo);
final int nativeWidth = dbo.outWidth;
final int nativeHeight = dbo.outHeight;
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "generateThumbnail: Input: " + nativeWidth + "x" + nativeHeight
+ ", resize to: " + width + "x" + height);
}
final Bitmap srcBitmap;
float bitmapWidth, bitmapHeight;
if (nativeWidth > width || nativeHeight > height) {
float dx = ((float)nativeWidth) / ((float)width);
float dy = ((float)nativeHeight) / ((float)height);
if (dx > dy) {
bitmapWidth = width;
bitmapHeight = nativeHeight / dx;
} else {
bitmapWidth = nativeWidth / dy;
bitmapHeight = height;
}
// Create the bitmap from file
if (nativeWidth / bitmapWidth > 1) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = nativeWidth / (int)bitmapWidth;
srcBitmap = BitmapFactory.decodeFile(filename, options);
} else {
srcBitmap = BitmapFactory.decodeFile(filename);
}
} else {
bitmapWidth = width;
bitmapHeight = height;
srcBitmap = BitmapFactory.decodeFile(filename);
}
if (srcBitmap == null) {
Log.e(TAG, "generateThumbnail: Cannot decode image bytes");
throw new IOException("Cannot decode file: " + mFilename);
}
// Create the canvas bitmap
final Bitmap bitmap = Bitmap.createBitmap((int)bitmapWidth, (int)bitmapHeight,
Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(srcBitmap, new Rect(0, 0, srcBitmap.getWidth(), srcBitmap.getHeight()),
new Rect(0, 0, (int)bitmapWidth, (int)bitmapHeight), sResizePaint);
// Release the source bitmap
srcBitmap.recycle();
return bitmap;
}
}