summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorjinwu <jinwu@codeaurora.org>2018-09-21 18:33:37 +0800
committerjinwu <jinwu@codeaurora.org>2018-09-21 18:33:37 +0800
commitbfab14264c6b8aee87d0383df8c00ca844c3bee4 (patch)
treee437b50633a272df6dcb0b88b6b189c7bf7abe89 /src
parenta26301351c28e820f6c2346ebd07265cfed14c8b (diff)
downloadandroid_packages_apps_Snap-bfab14264c6b8aee87d0383df8c00ca844c3bee4.tar.gz
android_packages_apps_Snap-bfab14264c6b8aee87d0383df8c00ca844c3bee4.tar.bz2
android_packages_apps_Snap-bfab14264c6b8aee87d0383df8c00ca844c3bee4.zip
SnapdraongCamera:add HEIF support
add option to allow user to save captured image with HEIF format. Change-Id: I267b783bf7e4f41f523ef2ac4fbb734657b8e827 CRs-Fixed: 2312764
Diffstat (limited to 'src')
-rwxr-xr-xsrc/com/android/camera/CaptureModule.java19
-rw-r--r--src/com/android/camera/MediaSaveService.java68
-rwxr-xr-xsrc/com/android/camera/SettingsActivity.java1
-rwxr-xr-xsrc/com/android/camera/SettingsManager.java11
-rwxr-xr-xsrc/com/android/camera/Storage.java66
-rwxr-xr-xsrc/com/android/camera/imageprocessor/PostProcessor.java16
6 files changed, 173 insertions, 8 deletions
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 7bfee3041..0c93f9b73 100755
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -31,6 +31,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Point;
@@ -2422,6 +2423,24 @@ public class CaptureModule implements CameraModule, PhotoController,
byte[] bytes = getJpegData(image);
+ if (mSettingsManager.getSavePictureFormat() ==
+ SettingsManager.HEIF_FORMAT) {
+ String value = mSettingsManager.getValue(
+ SettingsManager.KEY_JPEG_QUALITY);
+ int qualityNumber = getQualityNumber(value);
+ mActivity.getMediaSaveService().addHEIFImageFromJpeg(bytes,
+ title,date,null,image.getWidth(),image.getHeight(),
+ 0,null,mContentResolver,
+ mOnMediaSavedListener,qualityNumber,"heif");
+ image.close();
+ if (mLongshotActive) {
+ mLastJpegData = bytes;
+ } else {
+ mActivity.updateThumbnail(bytes);
+ }
+ return;
+ }
+
if (image.getFormat() == ImageFormat.RAW10) {
mActivity.getMediaSaveService().addRawImage(bytes, title,
"raw");
diff --git a/src/com/android/camera/MediaSaveService.java b/src/com/android/camera/MediaSaveService.java
index 217f44f27..8394162db 100644
--- a/src/com/android/camera/MediaSaveService.java
+++ b/src/com/android/camera/MediaSaveService.java
@@ -163,6 +163,23 @@ public class MediaSaveService extends Service {
t.execute();
}
+ public void addHEIFImageFromJpeg(byte[] data, String title, long date, Location loc,
+ int width, int height, int orientation, ExifInterface exif,
+ ContentResolver resolver, OnMediaSavedListener listener,
+ int qualitiy, String pictureFormat) {
+ if (isQueueFull()) {
+ Log.e(TAG, "Cannot add image when the queue is full");
+ return;
+ }
+ HEIFImageSaveTask t = new HEIFImageSaveTask(data, title, date, loc, width, height, orientation,
+ exif, resolver, listener, qualitiy, pictureFormat);
+ mMemoryUse += data.length;
+ if (isQueueFull()) {
+ onQueueFull();
+ }
+ t.execute();
+ }
+
public void addClearsightImage(byte[] clearsight, GImage bayer, GDepth.DepthMap depthMap,
String title, long date, Location loc, int width, int height,
int orientation, ExifInterface exif,
@@ -328,6 +345,57 @@ public class MediaSaveService extends Service {
}
}
+ private class HEIFImageSaveTask extends AsyncTask<Void, Void, Uri> {
+ private byte[] data;
+ private String title;
+ private long date;
+ private Location loc;
+ private int width, height;
+ private int orientation;
+ private ExifInterface exif;
+ private ContentResolver resolver;
+ private OnMediaSavedListener listener;
+ private int quality;
+ private String pictureFormat;
+
+ public HEIFImageSaveTask(byte[] data, String title, long date, Location loc,
+ int width, int height, int orientation, ExifInterface exif,
+ ContentResolver resolver, OnMediaSavedListener listener,
+ int quality,String pictureFormat) {
+ this.data = data;
+ this.title = title;
+ this.date = date;
+ this.loc = loc;
+ this.width = width;
+ this.height = height;
+ this.orientation = orientation;
+ this.exif = exif;
+ this.resolver = resolver;
+ this.listener = listener;
+ this.quality = quality;
+ this.pictureFormat = pictureFormat;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ @Override
+ protected Uri doInBackground(Void... params) {
+ return Storage.addHeifImage(
+ resolver,title,date,loc,orientation,exif,data,
+ width,height,quality,pictureFormat);
+ }
+
+ @Override
+ protected void onPostExecute(Uri uri) {
+ boolean previouslyFull = isQueueFull();
+ mMemoryUse -= data.length;
+ if (isQueueFull() != previouslyFull) onQueueAvailable();
+ }
+ }
+
private class ImageSaveTask extends AsyncTask <Void, Void, Uri> {
private byte[] data;
private String title;
diff --git a/src/com/android/camera/SettingsActivity.java b/src/com/android/camera/SettingsActivity.java
index e413090a4..e0330063a 100755
--- a/src/com/android/camera/SettingsActivity.java
+++ b/src/com/android/camera/SettingsActivity.java
@@ -452,6 +452,7 @@ public class SettingsActivity extends PreferenceActivity {
private void initializePreferences() {
updatePreference(SettingsManager.KEY_PICTURE_SIZE);
+ updatePreference(SettingsManager.KEY_PICTURE_FORMAT);
updatePreference(SettingsManager.KEY_VIDEO_QUALITY);
updatePreference(SettingsManager.KEY_EXPOSURE);
updatePreference(SettingsManager.KEY_VIDEO_HIGH_FRAME_RATE);
diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java
index 7640cb53b..4346f2599 100755
--- a/src/com/android/camera/SettingsManager.java
+++ b/src/com/android/camera/SettingsManager.java
@@ -102,6 +102,8 @@ public class SettingsManager implements ListMenu.SettingsListener {
public static final int SCENE_MODE_PROMODE_INT = SCENE_MODE_CUSTOM_START + 9;
public static final int SCENE_MODE_DEEPZOOM_INT = SCENE_MODE_CUSTOM_START + 10;
public static final int SCENE_MODE_DEEPPORTRAIT_INT = SCENE_MODE_CUSTOM_START + 11;
+ public static final int JPEG_FORMAT = 0;
+ public static final int HEIF_FORMAT = 1;
public static final String SCENE_MODE_DUAL_STRING = "100";
public static final String SCENE_MODE_SUNSET_STRING = "10";
public static final String SCENE_MODE_LANDSCAPE_STRING = "4";
@@ -124,6 +126,7 @@ public class SettingsManager implements ListMenu.SettingsListener {
public static final String KEY_CAMERA_ID = "pref_camera2_id_key";
public static final String KEY_SWITCH_CAMERA = "pref_camera2_switch_camera_key";
public static final String KEY_PICTURE_SIZE = "pref_camera2_picturesize_key";
+ public static final String KEY_PICTURE_FORMAT = "pref_camera2_picture_format_key";
public static final String KEY_ISO = "pref_camera2_iso_key";
public static final String KEY_EXPOSURE = "pref_camera2_exposure_key";
public static final String KEY_TIMER = "pref_camera2_timer_key";
@@ -1693,11 +1696,19 @@ public class SettingsManager implements ListMenu.SettingsListener {
return num_val;
}
+
+
public boolean isCamera2HDRSupport(){
String value = getValue(KEY_HDR);
return value != null && value.equals("enable");
}
+ public int getSavePictureFormat() {
+ String value = getValue(SettingsManager.KEY_PICTURE_FORMAT);
+ if (value == null) return 0;
+ return Integer.valueOf(value);
+ }
+
public boolean isZSLInHALEnabled(){
String value = getValue(KEY_ZSL);
String halZSLValue = mContext.getString(R.string.pref_camera2_zsl_entryvalue_hal_zsl);
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
index 13f65e14c..a71a88a47 100755
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -18,14 +18,18 @@ package com.android.camera;
import java.io.File;
import java.io.FileOutputStream;
+import java.io.IOException;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.ContentValues;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.location.Location;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
+import android.os.Handler;
import android.os.StatFs;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.ImageColumns;
@@ -35,6 +39,8 @@ import android.util.Log;
import com.android.camera.data.LocalData;
import com.android.camera.exif.ExifInterface;
import com.android.camera.util.ApiHelper;
+import androidx.heifwriter.HeifWriter;
+import android.graphics.ImageFormat;
public class Storage {
private static final String TAG = "CameraStorage";
@@ -135,13 +141,24 @@ public class Storage {
values.put(ImageColumns.TITLE, title);
if (mimeType.equalsIgnoreCase("jpeg") ||
mimeType.equalsIgnoreCase("image/jpeg") ||
+ mimeType.equalsIgnoreCase("heif") ||
mimeType == null) {
- values.put(ImageColumns.DISPLAY_NAME, title + ".jpg");
+
+ if (mimeType.equalsIgnoreCase("heif")){
+ values.put(ImageColumns.DISPLAY_NAME, title + ".heic");
+ } else {
+ values.put(ImageColumns.DISPLAY_NAME, title + ".jpg");
+ }
+
} else {
values.put(ImageColumns.DISPLAY_NAME, title + ".raw");
}
values.put(ImageColumns.DATE_TAKEN, date);
- values.put(ImageColumns.MIME_TYPE, "image/jpeg");
+ if (mimeType.equalsIgnoreCase("heif")) {
+ values.put(ImageColumns.MIME_TYPE, "image/heif");
+ } else {
+ values.put(ImageColumns.MIME_TYPE, "image/jpeg");
+ }
// Clockwise rotation in degrees. 0, 90, 180, or 270.
values.put(ImageColumns.ORIENTATION, orientation);
values.put(ImageColumns.DATA, path);
@@ -180,6 +197,40 @@ public class Storage {
return size;
}
+ public static Uri addHeifImage(ContentResolver resolver, String title, long date,
+ Location location, int orientation, ExifInterface exif, byte[] data, int width,
+ int height, int quality, String mimeType) {
+ String path = generateFilepath(title, mimeType);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length);
+ if (bitmap != null) {
+ try {
+ HeifWriter.Builder builder =
+ new HeifWriter.Builder(path,width, height,HeifWriter.INPUT_MODE_BITMAP);
+ builder.setQuality(quality);
+ builder.setMaxImages(1);
+ builder.setPrimaryIndex(0);
+ builder.setRotation(orientation);
+ HeifWriter heifWriter = builder.build();
+ heifWriter.start();
+ heifWriter.addBitmap(bitmap);
+ heifWriter.stop(3000);
+ heifWriter.close();
+ } catch (IOException|IllegalStateException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ bitmap.recycle();
+ }
+ File f = new File(path);
+ int size = 0;
+ if (f.exists() && f.isFile()) {
+ size = (int) f.length();
+ }
+ return addImage(resolver, title, date, location, orientation,
+ size, path, width, height, mimeType);
+ }
+
// Overwrites the file and updates the MediaStore, or inserts the image if
// one does not already exist.
public static void updateImage(Uri imageUri, ContentResolver resolver, String title, long date,
@@ -224,11 +275,16 @@ public class Storage {
}
public static String generateFilepath(String title, String pictureFormat) {
- if (pictureFormat == null || pictureFormat.equalsIgnoreCase("jpeg")) {
+ if (pictureFormat == null || pictureFormat.equalsIgnoreCase("jpeg")
+ || pictureFormat.equalsIgnoreCase("heif")) {
+ String suffix = ".jpg";
+ if (pictureFormat.equalsIgnoreCase("heif")) {
+ suffix = ".heic";
+ }
if (isSaveSDCard() && SDCard.instance().isWriteable()) {
- return SDCard.instance().getDirectory() + '/' + title + ".jpg";
+ return SDCard.instance().getDirectory() + '/' + title + suffix;
} else {
- return DIRECTORY + '/' + title + ".jpg";
+ return DIRECTORY + '/' + title + suffix;
}
} else {
return RAW_DIRECTORY + '/' + title + ".raw";
diff --git a/src/com/android/camera/imageprocessor/PostProcessor.java b/src/com/android/camera/imageprocessor/PostProcessor.java
index c227f32b2..f91f6b031 100755
--- a/src/com/android/camera/imageprocessor/PostProcessor.java
+++ b/src/com/android/camera/imageprocessor/PostProcessor.java
@@ -1278,9 +1278,19 @@ public class PostProcessor{
mController.showCapturedReview(bytes, orientation);
}
} else {
- mActivity.getMediaSaveService().addImage(
- bytes, title, date, null, image.getCropRect().width(), image.getCropRect().height(),
- orientation, null, mController.getMediaSavedListener(), mActivity.getContentResolver(), "jpeg");
+ if(SettingsManager.getInstance().getSavePictureFormat() ==
+ SettingsManager.HEIF_FORMAT) {
+ String value = SettingsManager.getInstance().getValue(
+ SettingsManager.KEY_JPEG_QUALITY);
+ int qualityNumber = CaptureModule.getQualityNumber(value);
+ mActivity.getMediaSaveService().addHEIFImageFromJpeg(bytes,title,date,null,
+ image.getWidth(),image.getHeight(),orientation,null,mActivity.getContentResolver(),
+ mController.getMediaSavedListener(),qualityNumber,"heif");
+ } else {
+ mActivity.getMediaSaveService().addImage(
+ bytes, title, date, null, image.getCropRect().width(), image.getCropRect().height(),
+ orientation, null, mController.getMediaSavedListener(), mActivity.getContentResolver(), "jpeg");
+ }
mController.updateThumbnailJpegData(bytes);
image.close();
}