ukryj menu
SPEC
aktualizacja: 2022-03-18 11:15:32
1. Scenariusz aplikacji na dziś
- MainActivity - przycisk Camera uruchamia Dialog z wyborem systemowej kamery lub galerii
- Dialog z listą folderów pozwala na wybór miejsca zapisu zdjęcia
- GalleryActivity - można przeglądać zdjęcia/pliki w wybranej galerii
- PhotoActivity - można zobaczyć powiększone dane zdjęcie, usunąć je, zmieniać sposób jego skalowania (dopasowania do ekranu)
2. Intents - pobranie danych z aparatu
z systemowego aparatu można uzyskać zdjęcia (miniatury) o niskiej jakości
a) Manifest
<uses-permission android:name="android.permission.CAMERA" />kopiuj
b) uruchomienie Intenta aparatu
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//jeśli jest dostępny aparat
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, 200); // 200 - stała wartość, która później posłuży do identyfikacji tej akcji
}kopiuj
//jeśli jest dostępny aparat
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, 200); // 200 - stała wartość, która później posłuży do identyfikacji tej akcji
}kopiuj
c) odebranie danych w MainActivity, w metodzie onActivityResult
(jest to metoda dziedziczona, jak onPause, onResume)
przed końcem klasy Activity piszemy onActivityRes...
generuje się odpowiednia metoda onActivityResult,
w niej sprawdzamy czy aparat zwrócił jakieś dane
if (requestCode == 200) {
if (resultCode == RESULT_OK) {
// tutaj są dostępne dane zdjęcia z aparatu, można je konwertować i zapisywać do pliku
}
}
kopiuj
if (resultCode == RESULT_OK) {
// tutaj są dostępne dane zdjęcia z aparatu, można je konwertować i zapisywać do pliku
}
}
kopiuj
d) pobranie danych z aparatu (w ten sposób można pobrać tylko thumbnail,
zdjęcie wysokiej jakości powinno się automatycznie zapisać w galerii systemowej)
Bundle extras = data.getExtras();
Bitmap b = (Bitmap) extras.get("data");
iv.setImageBitmap(b);kopiuj
Bitmap b = (Bitmap) extras.get("data");
iv.setImageBitmap(b);kopiuj
3. Intents - pobranie danych z galerii systemowej
z galerii można uzyskać zdjęcia o wysokiej jakości
a) uruchomienie Intenta galerii
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 100); // 100 - stała wartość, która później posłuży do identyfikacji tej akcji
kopiujb) odbiór danych z galerii
Uri imgData = data.getData();
InputStream stream = getContentResolver().openInputStream(imgData);
Bitmap b = BitmapFactory.decodeStream(stream);kopiuj
InputStream stream = getContentResolver().openInputStream(imgData);
Bitmap b = BitmapFactory.decodeStream(stream);kopiuj
4. konwersja danych typu Bitmap na zapisywalną do pliku tablicę byte[]
cała gotowa funkcja
ByteArrayOutputStream stream = new ByteArrayOutputStream();
anyBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); // kompresja, typ pliku jpg, png
byte[] byteArray = stream.toByteArray();kopiuj
anyBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); // kompresja, typ pliku jpg, png
byte[] byteArray = stream.toByteArray();kopiuj
5. zapis danych byte[] do pliku na urządzeniu
pełny kod
FileOutputStream fs = null;
fs = new FileOutputStream("pełna_ścieżka_pliku_zdjęcia.jpg");
fs.write(byteArray);
fs.close();kopiuj
fs = new FileOutputStream("pełna_ścieżka_pliku_zdjęcia.jpg");
fs.write(byteArray);
fs.close();kopiuj
6. nazwa zdjęcia - data bieżąca
https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmss");
String d = df.format(new Date());kopiuj
7. Dynamiczne tworzenie elementów UI
przykład na ImageView
tym razem inaczej niż poprzednio nie wykorzystamy ArrayAdaptera
do generowania ekranu ze zdjęciami
tylko dynamicznie wygenerujemy ImageViews
ImageView img = new ImageView(context);
linearLayout.addView(img);kopiuj
linearLayout.addView(img);kopiuj
8.
Prawidłowy odczyt zdjęć z katalogu
z ominięciem typowego problemu z
brakiem pamięci (OutOfMemory error) w aplikacjach androida:
a) czytamy for-em pliki z danego katalogu
for (...) {
//jeśli File jest plikiem
imagepath = ... // pobierz scieżkę z obiektu File
Bitmap bmp = betterImageDecode(imagepath); // własna funkcja betterImageDecode opisana jest poniżej
imageview.setImageBitmap(bmp); // wstawienie bitmapy do ImageView
}kopiuj
b) betterImageDecode
kluczowa funkcja zmniejszająca jakość bitmapy
Działanie funkcji polega na zmniejszeniu jakości zdjęcia
private Bitmap betterImageDecode(String filePath) {
Bitmap myBitmap;
BitmapFactory.Options options = new BitmapFactory.Options(); //opcje przekształcania bitmapy
options.inSampleSize = 4; // zmniejszenie jakości bitmapy 4x
//
myBitmap = BitmapFactory.decodeFile(filePath, options);
return myBitmap;
}kopiuj
Bitmap myBitmap;
BitmapFactory.Options options = new BitmapFactory.Options(); //opcje przekształcania bitmapy
options.inSampleSize = 4; // zmniejszenie jakości bitmapy 4x
//
myBitmap = BitmapFactory.decodeFile(filePath, options);
return myBitmap;
}kopiuj
patrz dokumentacja
https://developer.android.com/reference/android/graphics/BitmapFactory.Options#inSampleSize
9. Dopasowanie bitmapy w ImageView
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);kopiuj
https://developer.android.com/reference/android/widget/ImageView.ScaleType