blob: 8ac9a943c601940428baa8bbe3848c3181660131 [file] [log] [blame]
/*
* Copyright (C) 2013 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 com.android.camera.data;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.os.AsyncTask;
import android.provider.MediaStore.Images;
import com.android.camera.data.LocalMediaData.PhotoData;
import com.android.camera.debug.Log;
import com.android.camera.exif.ExifInterface;
import com.android.camera.exif.ExifTag;
import com.android.camera2.R;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* RotationTask can be used to rotate a {@link LocalData} by updating the exif
* data from jpeg file. Note that only {@link PhotoData} can be rotated.
*/
public class RotationTask extends AsyncTask<LocalData, Void, LocalData> {
private static final Log.Tag TAG = new Log.Tag("RotationTask");
private final Context mContext;
private final LocalDataAdapter mAdapter;
private final int mCurrentDataId;
private final boolean mClockwise;
private ProgressDialog mProgress;
public RotationTask(Context context, LocalDataAdapter adapter,
int currentDataId, boolean clockwise) {
mContext = context;
mAdapter = adapter;
mCurrentDataId = currentDataId;
mClockwise = clockwise;
}
@Override
protected void onPreExecute() {
// Show a progress bar since the rotation could take long.
mProgress = new ProgressDialog(mContext);
int titleStringId = mClockwise ? R.string.rotate_right : R.string.rotate_left;
mProgress.setTitle(mContext.getString(titleStringId));
mProgress.setMessage(mContext.getString(R.string.please_wait));
mProgress.setCancelable(false);
mProgress.show();
}
@Override
protected LocalData doInBackground(LocalData... data) {
return rotateInJpegExif(data[0]);
}
/**
* Rotates the image by updating the exif. Done in background thread.
* The worst case is the whole file needed to be re-written with
* modified exif data.
*
* @return A new {@link LocalData} object which containing the new info.
*/
private LocalData rotateInJpegExif(LocalData data) {
if (!(data instanceof PhotoData)) {
Log.w(TAG, "Rotation can only happen on PhotoData.");
return null;
}
PhotoData imageData = (PhotoData) data;
int originRotation = imageData.getRotation();
int finalRotationDegrees;
if (mClockwise) {
finalRotationDegrees = (originRotation + 90) % 360;
} else {
finalRotationDegrees = (originRotation + 270) % 360;
}
String filePath = imageData.getPath();
ContentValues values = new ContentValues();
boolean success = false;
int newOrientation = 0;
if (imageData.getMimeType().equalsIgnoreCase(LocalData.MIME_TYPE_JPEG)) {
ExifInterface exifInterface = new ExifInterface();
ExifTag tag = exifInterface.buildTag(
ExifInterface.TAG_ORIENTATION,
ExifInterface.getOrientationValueForRotation(
finalRotationDegrees));
if (tag != null) {
exifInterface.setTag(tag);
try {
// Note: This only works if the file already has some EXIF.
exifInterface.forceRewriteExif(filePath);
long fileSize = new File(filePath).length();
values.put(Images.Media.SIZE, fileSize);
newOrientation = finalRotationDegrees;
success = true;
} catch (FileNotFoundException e) {
Log.w(TAG, "Cannot find file to set exif: " + filePath);
} catch (IOException e) {
Log.w(TAG, "Cannot set exif data: " + filePath);
}
} else {
Log.w(TAG, "Cannot build tag: " + ExifInterface.TAG_ORIENTATION);
}
}
PhotoData result = null;
if (success) {
// MediaStore using SQLite is thread safe.
values.put(Images.Media.ORIENTATION, finalRotationDegrees);
mContext.getContentResolver().update(imageData.getUri(),
values, null, null);
double[] latLong = data.getLatLong();
double latitude = 0;
double longitude = 0;
if (latLong != null) {
latitude = latLong[0];
longitude = latLong[1];
}
result = new PhotoData(data.getContentId(), data.getTitle(),
data.getMimeType(), data.getDateTaken(), data.getDateModified(),
data.getPath(), newOrientation, imageData.getWidth(),
imageData.getHeight(), data.getSizeInBytes(), latitude, longitude);
}
return result;
}
@Override
protected void onPostExecute(LocalData result) {
mProgress.dismiss();
if (result != null) {
mAdapter.updateData(mCurrentDataId, result);
}
}
}