android - vectorial - modo de mapa de bits
Guardar mapa de bits en la ubicaciĆ³n (16)
Estoy trabajando en una función para descargar una imagen de un servidor web, mostrarla en la pantalla y, si el usuario desea guardar la imagen, guárdela en la tarjeta SD en una carpeta determinada. ¿Hay una manera fácil de tomar un mapa de bits y simplemente guardarlo en la tarjeta SD en una carpeta de mi elección?
Mi problema es que puedo descargar la imagen, mostrarla en pantalla como un mapa de bits. La única forma en que he podido encontrar para guardar una imagen en una carpeta en particular es usar FileOutputStream, pero eso requiere una matriz de bytes. No estoy seguro de cómo convertir (si esta es la forma correcta) de Bitmap a byte array, por lo que puedo usar un FileOutputStream para escribir los datos.
La otra opción que tengo es usar MediaStore:
MediaStore.Images.Media.insertImage(getContentResolver(), bm,
barcodeNumber + ".jpg Card Image", barcodeNumber + ".jpg Card Image");
Lo que funciona bien para guardar en la tarjeta SD, pero no le permite personalizar la carpeta.
¿Por qué no llamar al método Bitmap.compress
con 100 (lo que parece que no tiene pérdidas)?
// | == | Crea un archivo PNG desde Bitmap:
void devImjFylFnc(String pthAndFylTtlVar, Bitmap iptBmjVar)
{
try
{
FileOutputStream fylBytWrtrVar = new FileOutputStream(pthAndFylTtlVar);
iptBmjVar.compress(Bitmap.CompressFormat.PNG, 100, fylBytWrtrVar);
fylBytWrtrVar.close();
}
catch (Exception errVar) { errVar.printStackTrace(); }
}
// | == | Obtener Bimap desde el archivo:
Bitmap getBmjFrmFylFnc(String pthAndFylTtlVar)
{
return BitmapFactory.decodeFile(pthAndFylTtlVar);
}
Algunos formatos, como PNG que no tiene pérdidas, ignorarán la configuración de calidad.
Aquí está el código de ejemplo para guardar el mapa de bits en el archivo:
public static File savebitmap(Bitmap bmp) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 60, bytes);
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "testimage.jpg");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
return f;
}
Ahora llame a esta función para guardar el mapa de bits en la memoria interna.
File newfile = savebitmap(bitmap)
;
Espero que te ayude. Feliz vida codificadora.
Asegúrese de que el directorio esté creado antes de llamar a bitmap.compress
:
new File(FileName.substring(0,FileName.lastIndexOf("/"))).mkdirs();
Crear una miniatura de video para un video. Puede devolver nulo si el video está dañado o el formato no es compatible.
private void makeVideoPreview() {
Bitmap thumbnail = ThumbnailUtils.createVideoThumbnail(videoAbsolutePath, MediaStore.Images.Thumbnails.MINI_KIND);
saveImage(thumbnail);
}
Para guardar su mapa de bits en sdcard use el siguiente código
Imagen de tienda
private void storeImage(Bitmap image) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d(TAG,
"Error creating media file, check storage permissions: ");// e.getMessage());
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
Para obtener el camino para el almacenamiento de imágenes
/** Create a File for saving an image or video */
private File getOutputMediaFile(){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ getApplicationContext().getPackageName()
+ "/Files");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName="MI_"+ timeStamp +".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
Debe usar el método Bitmap.compress()
para guardar un mapa de bits como un archivo. Comprimirá (si el formato utilizado lo permite) su imagen y la insertará en un OutputStream.
Aquí hay un ejemplo de una instancia de Bitmap obtenida a través de getImageBitmap(myurl)
que se puede comprimir como un JPEG con una tasa de compresión del 85%:
// Assume block needs to be inside a Try/Catch block.
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
Integer counter = 0;
File file = new File(path, "FitnessGirl"+counter+".jpg"); // the File to save , append increasing numeric counter to prevent files from getting overwritten.
fOut = new FileOutputStream(file);
Bitmap pictureBitmap = getImageBitmap(myurl); // obtaining the Bitmap
pictureBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut); // saving the Bitmap to a file compressed as a JPEG with 85% compression rate
fOut.flush(); // Not really required
fOut.close(); // do not forget to close the stream
MediaStore.Images.Media.insertImage(getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
Dentro de onActivityResult
:
String filename = "pippo.png";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
try {
FileOutputStream out = new FileOutputStream(dest);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Después de Android 4.4 Kitkat, y a partir de 2017, la cuota de Android 4.4 y menos es aproximadamente un 20% y está disminuyendo, no es posible guardar en la tarjeta SD utilizando la clase de File
y el método getExternalStorageDirectory()
Este método devuelve la memoria interna de su dispositivo y las imágenes guardadas visibles para cada aplicación. También puede guardar imágenes solo privadas para su aplicación y eliminarlas cuando el usuario elimine su aplicación con el método openFileOutput()
.
A partir de Android 6.0, puede formatear su tarjeta SD como una memoria interna pero solo privada para su dispositivo. (Si formatea un automóvil SD como memoria interna, solo su dispositivo puede acceder o ver su contenido) Puede guardar en esa tarjeta SD usando otras respuestas, pero si desea utilizar una tarjeta SD extraíble, debe leer mi respuesta a continuación.
Debe usar Storage Access Framework para obtener uri en la carpeta en el método de actividad onActivityResult
para obtener la carpeta seleccionada por el usuario, y agregar un permiso persistente de recuperación para poder acceder a la carpeta después de que el usuario reinicie el dispositivo.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
// selectDirectory() invoked
if (requestCode == REQUEST_FOLDER_ACCESS) {
if (data.getData() != null) {
Uri treeUri = data.getData();
tvSAF.setText("Dir: " + data.getData().toString());
currentFolder = treeUri.toString();
saveCurrentFolderToPrefs();
// grantUriPermission(getPackageName(), treeUri,
// Intent.FLAG_GRANT_READ_URI_PERMISSION |
// Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
}
}
}
}
Ahora, guarde la carpeta de guardar en las preferencias compartidas para no pedirle al usuario que seleccione una carpeta cada vez que quiera guardar una imagen.
Debe usar DocumentFile
clase DocumentFile
para guardar su imagen, no File
o ParcelFileDescriptor
, para obtener más información, puede revisar este hilo para guardar la imagen en la tarjeta SD con compress(CompressFormat.JPEG, 100, out);
Método y clases de DocumentFile
.
En realidad no es una respuesta, sino un comentario. Estoy en una Mac ejecutando el entorno del emulador y obtengo una excepción java.io.IOException: Permiso denegado - error con este código:
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
Log.d("DEBUG", "onActivityResult called");
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if(requestCode == 0 && resultCode == RESULT_OK) {
Log.d("DEBUG", "result is ok");
try{
Bitmap map = (Bitmap) imageReturnedIntent.getExtras().get("data");
File sd = new File(Environment.getExternalStorageDirectory(), "test.png");
sd.mkdirs();
sd.createNewFile();
FileOutputStream out = new FileOutputStream(sd);
map.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch(FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
También agregué use-permission android.permission.WRITE_EXTERNAL_STORAGE al archivo de manifiesto (como lo anotaron otros).
Hey solo dale el nombre a .bmp
Hacer esto:
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
_bitmapScaled.compress(Bitmap.CompressFormat.PNG, 40, bytes);
//you can create a new file name "test.BMP" in sdcard folder.
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "**test.bmp**")
Sonará como si solo hubiera perdido el tiempo pero inténtelo una vez que se guardará en bmp foramt..Cheers
La forma en que encontré para enviar PNG y transparencia.
String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/CustomDir";
File dir = new File(file_path);
if(!dir.exists())
dir.mkdirs();
String format = new SimpleDateFormat("yyyyMMddHHmmss",
java.util.Locale.getDefault()).format(new Date());
File file = new File(dir, format + ".png");
FileOutputStream fOut;
try {
fOut = new FileOutputStream(file);
yourbitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "");
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(intent,"Sharing something")));
También me gustaría guardar una foto. Pero mi problema (?) Es que quiero guardarlo de un mapa de bits que he dibujado.
Lo hice así:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save_sign:
myView.save();
break;
}
return false;
}
public void save() {
String filename;
Date date = new Date(0);
SimpleDateFormat sdf = new SimpleDateFormat ("yyyyMMddHHmmss");
filename = sdf.format(date);
try{
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
File file = new File(path, "/DCIM/Signatures/"+filename+".jpg");
fOut = new FileOutputStream(file);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(getContentResolver()
,file.getAbsolutePath(),file.getName(),file.getName());
}catch (Exception e) {
e.printStackTrace();
}
}
Bitmap bbicon;
bbicon=BitmapFactory.decodeResource(getResources(),R.drawable.bannerd10);
//ByteArrayOutputStream baosicon = new ByteArrayOutputStream();
//bbicon.compress(Bitmap.CompressFormat.PNG,0, baosicon);
//bicon=baosicon.toByteArray();
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
OutputStream outStream = null;
File file = new File(extStorageDirectory, "er.PNG");
try {
outStream = new FileOutputStream(file);
bbicon.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch(Exception e) {
}
outStream = new FileOutputStream(file);
lanzará una excepción sin permiso en AndroidManifest.xml (al menos en os2.2):
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
try (FileOutputStream out = new FileOutputStream(filename)) {
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (IOException e) {
e.printStackTrace();
}