1fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford/* 2fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Copyright (C) 2015 The Android Open Source Project 3fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * 4fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Licensed under the Apache License, Version 2.0 (the "License"); 5fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * you may not use this file except in compliance with the License. 6fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * You may obtain a copy of the License at 7fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * 8fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * http://www.apache.org/licenses/LICENSE-2.0 9fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * 10fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Unless required by applicable law or agreed to in writing, software 11fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * distributed under the License is distributed on an "AS IS" BASIS, 12fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * See the License for the specific language governing permissions and 14fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * limitations under the License. 15fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 16fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 17fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordpackage com.android.example.rscamera; 18fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 19fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.io.FileNotFoundException; 20fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.io.IOException; 21fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport java.io.OutputStream; 22fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 23fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.content.ContentResolver; 24fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.content.ContentUris; 25fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.content.ContentValues; 26fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.graphics.Bitmap; 27fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.graphics.Matrix; 28fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.net.Uri; 29fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.provider.MediaStore; 30fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordimport android.provider.MediaStore.Images; 31fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 32fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford/** 33fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * Utility class to save images into android image database 34fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 35fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hofordpublic class MediaStoreSaver { 36fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public static interface StreamWriter { 37fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford void write(OutputStream imageOut) throws IOException; 38fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 39fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 40fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public static final String insertImage(ContentResolver contentResolver, 41fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Bitmap image, 42fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String title, 43fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String description) { 44fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford final Bitmap source = image; 45fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford StreamWriter streamWriter = new StreamWriter() { 46fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public void write(OutputStream imageOut) { 47fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut); 48fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 49fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford }; 50fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return insertImage(contentResolver, streamWriter, title, description); 51fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 52fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 53fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 54fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford public static final String insertImage(ContentResolver cr, 55fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford StreamWriter source, 56fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String title, 57fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String description) { 58fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 59fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford ContentValues values = new ContentValues(); 60fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Media.TITLE, title); 61fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Media.DISPLAY_NAME, title); 62fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Media.DESCRIPTION, description); 63fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Media.MIME_TYPE, "image/jpeg"); 64fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // Add the date meta data to ensure the image is added at the front of the gallery 65fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Media.DATE_ADDED, System.currentTimeMillis()); 66fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis()); 67fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 68fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Uri url = null; 69fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford String stringUrl = null; /* value to be returned */ 70fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 71fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 72fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 73fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 74fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (source != null) { 75fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford OutputStream imageOut = cr.openOutputStream(url); 76fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 77fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford source.write(imageOut); 78fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } finally { 79fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford imageOut.close(); 80fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 81fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 82fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford long id = ContentUris.parseId(url); 83fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // Wait until MINI_KIND thumbnail is generated. 84fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MINI_KIND, null); 85fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // This is for backward compatibility. 86fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford storeThumbnail(cr, miniThumb, id, 50F, 50F, Images.Thumbnails.MICRO_KIND); 87fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } else { 88fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford cr.delete(url, null, null); 89fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford url = null; 90fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 91fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (Exception e) { 92fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (url != null) { 93fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford cr.delete(url, null, null); 94fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford url = null; 95fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 96fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 97fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 98fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford if (url != null) { 99fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford stringUrl = url.toString(); 100fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 101fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 102fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return stringUrl; 103fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 104fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 105fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford /** 106fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * A copy of the Android internals StoreThumbnail method, it used with the insertImage to 107fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * populate the android.provider.MediaStore.Images.Media#insertImage with all the correct 108fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * meta data. The StoreThumbnail method is private so it must be duplicated here. 109fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * 110fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford * @see android.provider.MediaStore.Images.Media (StoreThumbnail private method) 111fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford */ 112fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford private static final Bitmap storeThumbnail( 113fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford ContentResolver cr, 114fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Bitmap source, 115fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford long id, 116fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford float width, 117fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford float height, 118fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford int kind) { 119fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 120fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford // create the matrix to scale it 121fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Matrix matrix = new Matrix(); 122fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 123fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford float scaleX = width / source.getWidth(); 124fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford float scaleY = height / source.getHeight(); 125fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 126fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford matrix.setScale(scaleX, scaleY); 127fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 128fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Bitmap thumb = Bitmap.createBitmap(source, 0, 0, 129fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford source.getWidth(), 130fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford source.getHeight(), matrix, 131fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford true 132fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford ); 133fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 134fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford ContentValues values = new ContentValues(4); 135fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Thumbnails.KIND, kind); 136fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Thumbnails.IMAGE_ID, (int) id); 137fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Thumbnails.HEIGHT, thumb.getHeight()); 138fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford values.put(Images.Thumbnails.WIDTH, thumb.getWidth()); 139fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 140fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford Uri url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values); 141fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 142fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford try { 143fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford OutputStream thumbOut = cr.openOutputStream(url); 144fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut); 145fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford thumbOut.close(); 146fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return thumb; 147fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (FileNotFoundException ex) { 148fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return null; 149fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } catch (IOException ex) { 150fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford return null; 151fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 152fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford } 153fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 154fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford 155fbb9dd1843197a0d2f7fcda29abbe9d170682a5dJohn Hoford} 156