diff options
| -rw-r--r-- | main/res/layout/visit_image.xml | 7 | ||||
| -rw-r--r-- | main/res/values-de/strings.xml | 10 | ||||
| -rw-r--r-- | main/res/values/strings.xml | 8 | ||||
| -rw-r--r-- | main/res/values/strings_not_translatable.xml | 12 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/ImageSelectActivity.java | 50 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/Settings.java | 15 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/utils/ImageHelper.java | 38 |
7 files changed, 137 insertions, 3 deletions
diff --git a/main/res/layout/visit_image.xml b/main/res/layout/visit_image.xml index 7997406..c9d4be2 100644 --- a/main/res/layout/visit_image.xml +++ b/main/res/layout/visit_image.xml @@ -98,6 +98,13 @@ android:minLines="5" android:singleLine="false" /> + <Spinner + android:id="@+id/logImageScale" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:prompt="@string/log_image_scale" + android:entries="@array/log_image_scales"/> + <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" diff --git a/main/res/values-de/strings.xml b/main/res/values-de/strings.xml index 048991b..ab0b11e 100644 --- a/main/res/values-de/strings.xml +++ b/main/res/values-de/strings.xml @@ -125,7 +125,15 @@ <string name="log_image_camera">Neu</string> <string name="log_image_caption">Überschrift</string> <string name="log_image_description">Beschreibung</string> - + <string name="log_image_scale">Skalierung</string> + <string-array name="log_image_scales"> + <item>Keine Skalierung</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> + <!-- translation --> <string name="translate_to_sys_lang">Übersetze in %s</string> <string name="translate_to_english">Übersetze in Englisch</string> diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml index d35a982..28a57e0 100644 --- a/main/res/values/strings.xml +++ b/main/res/values/strings.xml @@ -126,6 +126,14 @@ <string name="log_image_camera">New</string> <string name="log_image_caption">Caption</string> <string name="log_image_description">Description</string> + <string name="log_image_scale">Scaling</string> + <string-array name="log_image_scales"> + <item>No scaling</item> + <item>512 px</item> + <item>640 px</item> + <item>800 px</item> + <item>1024 px</item> + </string-array> <!-- translation --> <string name="translate_to_sys_lang">Translate to %s</string> diff --git a/main/res/values/strings_not_translatable.xml b/main/res/values/strings_not_translatable.xml index b392d73..1eddfc6 100644 --- a/main/res/values/strings_not_translatable.xml +++ b/main/res/values/strings_not_translatable.xml @@ -28,6 +28,15 @@ <string name="init_select_gpx_exportdir" translatable="false">…</string>
<string name="init_select_gpx_importdir" translatable="false">…</string>
+ <!-- upload image scaling -->
+ <integer-array name="log_image_scale_values">
+ <item>-1</item>
+ <item>512</item>
+ <item>640</item>
+ <item>800</item>
+ <item>1024</item>
+ </integer-array>
+
<!-- contributors -->
<string name="contributors" translatable="false">\n
· <a href="http://carnero.cc/">carnero</a> as the father of c:geo\n
@@ -89,7 +98,8 @@ <string name="changelog" translatable="false">\n
<b>Next release</b>\n\n
<b>New Features/Functions:</b>\n
- · ...\n
+ · Log images can be scaled before upload to save traffic
+ · \n
\n
<b>Bugfixing:</b>\n
· Do not apply encryption/decryption when clicking on a link in a log\n
diff --git a/main/src/cgeo/geocaching/ImageSelectActivity.java b/main/src/cgeo/geocaching/ImageSelectActivity.java index 347cd86..597a7bd 100644 --- a/main/src/cgeo/geocaching/ImageSelectActivity.java +++ b/main/src/cgeo/geocaching/ImageSelectActivity.java @@ -2,6 +2,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.compatibility.Compatibility; +import cgeo.geocaching.utils.ImageHelper; import cgeo.geocaching.utils.Log; import org.apache.commons.lang3.StringUtils; @@ -10,14 +11,18 @@ import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.provider.MediaStore.MediaColumns; import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; +import android.widget.Spinner; import java.io.File; import java.text.SimpleDateFormat; @@ -28,20 +33,24 @@ public class ImageSelectActivity extends AbstractActivity { static final String EXTRAS_CAPTION = "caption"; static final String EXTRAS_DESCRIPTION = "description"; static final String EXTRAS_URI_AS_STRING = "uri"; + static final String EXTRAS_SCALE = "scale"; private static final String SAVED_STATE_IMAGE_CAPTION = "cgeo.geocaching.saved_state_image_caption"; private static final String SAVED_STATE_IMAGE_DESCRIPTION = "cgeo.geocaching.saved_state_image_description"; private static final String SAVED_STATE_IMAGE_URI = "cgeo.geocaching.saved_state_image_uri"; + private static final String SAVED_STATE_IMAGE_SCALE = "cgeo.geocaching.saved_state_image_scale"; private static final int SELECT_NEW_IMAGE = 1; private static final int SELECT_STORED_IMAGE = 2; private EditText captionView; private EditText descriptionView; + private Spinner scaleView; // Data to be saved while reconfiguring private String imageCaption; private String imageDescription; + private int scaleChoiceIndex; private Uri imageUri; public ImageSelectActivity() { @@ -56,6 +65,7 @@ public class ImageSelectActivity extends AbstractActivity { setContentView(R.layout.visit_image); setTitle(res.getString(R.string.log_image)); + scaleChoiceIndex = Settings.getLogImageScale(); imageCaption = ""; imageDescription = ""; imageUri = Uri.EMPTY; @@ -66,6 +76,7 @@ public class ImageSelectActivity extends AbstractActivity { imageCaption = extras.getString(EXTRAS_CAPTION); imageDescription = extras.getString(EXTRAS_DESCRIPTION); imageUri = Uri.parse(extras.getString(EXTRAS_URI_AS_STRING)); + scaleChoiceIndex = extras.getInt(EXTRAS_SCALE, scaleChoiceIndex); } // Restore previous state @@ -73,6 +84,7 @@ public class ImageSelectActivity extends AbstractActivity { imageCaption = savedInstanceState.getString(SAVED_STATE_IMAGE_CAPTION); imageDescription = savedInstanceState.getString(SAVED_STATE_IMAGE_DESCRIPTION); imageUri = Uri.parse(savedInstanceState.getString(SAVED_STATE_IMAGE_URI)); + scaleChoiceIndex = savedInstanceState.getInt(SAVED_STATE_IMAGE_SCALE); } final Button cameraButton = (Button) findViewById(R.id.camera); @@ -103,6 +115,20 @@ public class ImageSelectActivity extends AbstractActivity { descriptionView.setText(imageDescription); } + scaleView = (Spinner) findViewById(R.id.logImageScale); + scaleView.setSelection(scaleChoiceIndex); + scaleView.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { + scaleChoiceIndex = scaleView.getSelectedItemPosition(); + Settings.setLogImageScale(scaleChoiceIndex); + } + + @Override + public void onNothingSelected(AdapterView<?> arg0) { + } + }); + final Button saveButton = (Button) findViewById(R.id.save); saveButton.setOnClickListener(new View.OnClickListener() { @@ -131,15 +157,19 @@ public class ImageSelectActivity extends AbstractActivity { outState.putString(SAVED_STATE_IMAGE_CAPTION, imageCaption); outState.putString(SAVED_STATE_IMAGE_DESCRIPTION, imageDescription); outState.putString(SAVED_STATE_IMAGE_URI, imageUri != null ? imageUri.getPath() : StringUtils.EMPTY); + outState.putInt(SAVED_STATE_IMAGE_SCALE, scaleChoiceIndex); } public void saveImageInfo(boolean saveInfo) { if (saveInfo) { + String filename = writeScaledImage(imageUri.getPath()); + imageUri = Uri.parse(filename); Intent intent = new Intent(); syncEditTexts(); intent.putExtra(EXTRAS_CAPTION, imageCaption); intent.putExtra(EXTRAS_DESCRIPTION, imageDescription); intent.putExtra(EXTRAS_URI_AS_STRING, imageUri.toString()); + intent.putExtra(EXTRAS_SCALE, scaleChoiceIndex); setResult(RESULT_OK, intent); } else { @@ -152,6 +182,7 @@ public class ImageSelectActivity extends AbstractActivity { private void syncEditTexts() { imageCaption = captionView.getText().toString(); imageDescription = descriptionView.getText().toString(); + scaleChoiceIndex = scaleView.getSelectedItemPosition(); } private void selectImageFromCamera() { @@ -231,6 +262,25 @@ public class ImageSelectActivity extends AbstractActivity { loadImagePreview(); } + /** + * Scales and writes the scaled image. + * + * @param filePath + * @return + */ + private String writeScaledImage(String filePath) { + Bitmap image = BitmapFactory.decodeFile(filePath); + scaleChoiceIndex = scaleView.getSelectedItemPosition(); + int maxXY = getResources().getIntArray(R.array.log_image_scale_values)[scaleChoiceIndex]; + String uploadFilename = filePath; + if (maxXY > 0) { + BitmapDrawable scaledImage = ImageHelper.scaleBitmapTo(image, maxXY, maxXY); + uploadFilename = getOutputImageFile().getPath(); + ImageHelper.storeBitmap(scaledImage.getBitmap(), Bitmap.CompressFormat.JPEG, 75, uploadFilename); + } + return uploadFilename; + } + private void showFailure() { showToast(getResources().getString(R.string.err_aquire_image_failed)); } diff --git a/main/src/cgeo/geocaching/Settings.java b/main/src/cgeo/geocaching/Settings.java index 93bfa9b..b5c8a6e 100644 --- a/main/src/cgeo/geocaching/Settings.java +++ b/main/src/cgeo/geocaching/Settings.java @@ -112,6 +112,7 @@ public final class Settings { private static final String KEY_MAP_DIRECTORY = "mapDirectory"; private static final String KEY_CONNECTOR_OC_ACTIVE = "connectorOCActive"; private static final String KEY_CONNECTOR_OC_USER = "connectorOCUser"; + private static final String KEY_LOG_IMAGE_SCALE = "logImageScale"; private final static int unitsMetric = 1; @@ -1439,4 +1440,18 @@ public final class Settings { public static void setCacheTwitterMessage(final String message) { cacheTwitterMessage = message; } + + public static int getLogImageScale() { + return sharedPrefs.getInt(KEY_LOG_IMAGE_SCALE, -1); + } + + public static void setLogImageScale(final int scale) { + editSharedSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putInt(KEY_LOG_IMAGE_SCALE, scale); + } + }); + } } diff --git a/main/src/cgeo/geocaching/utils/ImageHelper.java b/main/src/cgeo/geocaching/utils/ImageHelper.java index 98cad64..ec77018 100644 --- a/main/src/cgeo/geocaching/utils/ImageHelper.java +++ b/main/src/cgeo/geocaching/utils/ImageHelper.java @@ -8,6 +8,9 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; +import java.io.BufferedOutputStream; +import java.io.FileOutputStream; + public class ImageHelper { // Do not let this class be instantiated, this is a utility class. @@ -22,11 +25,21 @@ public class ImageHelper { * @return BitmapDrawable The scaled image */ public static BitmapDrawable scaleBitmapToFitDisplay(final Bitmap image) { - final cgeoapplication app = cgeoapplication.getInstance(); Point displaySize = Compatibility.getDisplaySize(); final int maxWidth = displaySize.x - 25; final int maxHeight = displaySize.y - 25; + return scaleBitmapTo(image, maxWidth, maxHeight); + } + /** + * Scales a bitmap to the given bounds if it is larger, otherwise returns the original bitmap. + * + * @param image + * The bitmap to scale + * @return BitmapDrawable The scaled image + */ + public static BitmapDrawable scaleBitmapTo(final Bitmap image, final int maxWidth, final int maxHeight) { + final cgeoapplication app = cgeoapplication.getInstance(); Bitmap result = image; int width = image.getWidth(); int height = image.getHeight(); @@ -43,4 +56,27 @@ public class ImageHelper { return resultDrawable; } + /** + * Store a bitmap to file. + * + * @param bitmap + * The bitmap to store + * @param format + * The image format + * @param quality + * The image quality + * @param pathOfOutputImage + * Path to store to + */ + public static void storeBitmap(final Bitmap bitmap, final Bitmap.CompressFormat format, final int quality, final String pathOfOutputImage) { + try { + FileOutputStream out = new FileOutputStream(pathOfOutputImage); + BufferedOutputStream bos = new BufferedOutputStream(out); + bitmap.compress(format, quality, bos); + bos.flush(); + bos.close(); + } catch (Exception e) { + Log.e("Image", e); + } + } } |
