Dodanie do zdjęcia gifa

0

Hej, mam takie do was pytanko.
Otóż robię prostą aplikację a przynajmniej tak myślałem na początku :) Aplikacja jak na razie robi zdjęcie, ale chciałbym dodać do tego zdjęcia jakąś dynamiczną ozdobę, typu gif.
Tylko nie mam pojęcia jak się do tego zabrać. Spróbuję to wyjaśnić na przykładzie. Odpalam aplikację i od razu włącza mi się aparat, chce zrobić zdjęcie córce i podczas robienia tego zdjęcia pojawiają mi się latające motylki, klikam "zrób zdjęcie" i te motylki zostają zapisane na tym zdjęciu już nie latające, ale statyczne. No a poźniej to już jakiś zapis zdjęcia lub wysłanie na np. facebooka ale tym się będę później martwił :) Jak by ktoś wiedział jak się do tego zabrać lub widziałcoś kiedyś podobnego w internetach to bardzo proszę o pomoc :)

0

To wcale nie jest proste. Sugeruję raczej poszukać jakiejś biblioteki do manipulacji obrazami, bo temat jest skomplikowany.

0

Dzięki za komentarze i szybką reakcję :) Tak jak doradziliście raczej zostanę przy nałożeniu statycznej dekoracji. Tylko czy znacie może jakieś nowsze tutoriale gdzie ktoś coś podobnego robi żeby się w jakiś sposób nakierować ? Trochę szukałem i wszytko jest z przed 3-4 lat ;/

0

Może nie do końca to, czego potrzebujesz, ale ładnie jest tutaj zaprezentowane, jak działać z Canvasem. Musisz wtedy utworzyć Canvas ze zrobionego zdjęcia i na nim działać.

0

Powodzenia ze zdjęciem 20 MPix

0

wyglada na to ze mozna, i to na kilka sposobow:
https://stackoverflow.com/questions/3660209/display-animated-gif

0
Krzywy Programista napisał(a):

Powodzenia ze zdjęciem 20 MPix

A jaki jest problem z przeskalowaniem bitmapy? Poza tym, jeżeli w planach jest też coś takiego, jak wysyłanie zdjęć na FB, to nie będą one raczej aż tak duże.

EDIT:
Żeby nie było - nie mówię, że praca z obrazem, bitmapami, itd. jest prosta. Niemniej, jest na pewno możliwa.

0

No to spróbuj zdekompresować jpeg-a 20 megapiksel do bitmapy, a potem go skompresować znów do jpeg. Wiesz ile pamięci by to zajęło? Dalej twierdzisz że to proste? Oczywiście dostaniesz od razu wyjątek braku pamięci dla każdej fotki większej niż 640x480.

Zadanie na dziś - bitmapa z dekompresji jpeg 20 Mp, ile zajmie w pamięci RAM.

Można oczywiście zdekompresować tylko miniaturę i będzie to już od razu przeskalowane, tyle że autor chyba chce nałożyć coś na zdjęcie bez 10-ktotnego zmniejszenia rozdzielczości.

Jedyne wyjście to przetwarzać obrazek partiami, co znacznie komplikuje sprawę i będzie powolne. Żeby zrobić to optymalnie, trzeba pewnie by sięgnąć do ndk i tą część zrobić natywnie w C++

Dlatego lepiej poszukać liba, który odwali to za ciebie, bo temat nie jest wcale prosty

0

Nie wiem dokładnie, bo mi profiler coś w AS nie chce działać. W każdym razie JPEG 3840x5760, 4.3 MB ładował się 400-500 ms i zapisywał 700-900 ms. Stan wyjściowy JPEG 3840x5760, 1.5 MB przy kompresji 90 i 4.1 MB przy kompresji 100. Jakaś tam starta na jakości niby jest, ale na oko nie widzę. Kod raczej pisany na szybko niż z myślą o optymalizacji i wątkowości. Pomiar czasu też pi razy drzwi. Jakby zdjęcie było niepotrzebnie duże to można zawsze presampling włączyć dla BitmapFactory albo skalowanie przy zapisie. Co kto woli.

W sumie mam też dosyć szybki telefon, więc wyniki tak sobie przyadtne dla większości, ale dlatego też wspomniałem o downsamplingu, itd.

No i nie wiem, gdzie niby pisałem, że sprawa obróbki obrazu jest prosta. Zaznaczyłem w poprzednim poście wprost, że nie jest.

class MainActivity : Activity() {

  private var galleryUri: Uri? = null

  private val findImage by lazy { findViewById<Button>(R.id.findImage) }
  private val imageUri by lazy { findViewById<TextView>(R.id.imageUri) }
  private val loadImage by lazy { findViewById<Button>(R.id.loadImage) }
  private val loadInfo by lazy { findViewById<TextView>(R.id.loadInfo) }
  private val saveImage by lazy { findViewById<Button>(R.id.saveImage) }
  private val saveInfo by lazy { findViewById<TextView>(R.id.saveInfo) }
  private val image by lazy { findViewById<ImageView>(R.id.image) }

  override fun onCreate(inState: Bundle?) {
    super.onCreate(inState)
    setContentView(R.layout.main)

    findImage.setOnClickListener {
      val intent = Intent(ACTION_PICK).apply {
        type = "image/*"
      }
      startActivityForResult(intent, FIND_IMAGE_RESULT)
    }
    loadImage.setOnClickListener {
      val uri = galleryUri
      if (uri == null) {
        Toast.makeText(this@MainActivity, "No URI", LENGTH_SHORT).show()
        return@setOnClickListener
      }
      val start = System.currentTimeMillis()
      val imageStream = contentResolver.openInputStream(uri)
      image.setImageBitmap(BitmapFactory.decodeStream(imageStream))
      val end = System.currentTimeMillis()
      loadInfo.text = String.format("Load time: %d ms", end - start)
    }
    saveImage.setOnClickListener {
      if (checkSelfPermission(WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
        Toast.makeText(this@MainActivity, "Permission not granted", LENGTH_SHORT).show()
        return@setOnClickListener
      }
      val start = System.currentTimeMillis()
      val drawable = image.drawable as BitmapDrawable
      val root = Environment.getExternalStorageDirectory().toString()
      val dir = File(root + "/scaling")
      dir.mkdirs()
      val file = File(dir, "my_image.jpg")
      if (file.exists()) {
        file.delete()
      }
      FileOutputStream(file).use {
        drawable.bitmap.compress(JPEG, 100, it)
      }
      val end = System.currentTimeMillis()
      saveInfo.text = String.format("Save time: %d ms", end - start)
    }

    if (checkSelfPermission(WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
      requestPermissions(arrayOf(WRITE_EXTERNAL_STORAGE), WRITE_EXTERNAL_PERMISSION_RESULT)
    }
  }

  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (resultCode == RESULT_OK && requestCode == FIND_IMAGE_RESULT) {
      galleryUri = data?.data
      imageUri.text = String.format("File URI: %s", galleryUri?.toString() ?: "N/A")
    }
  }
}

private const val FIND_IMAGE_RESULT = 200
private const val WRITE_EXTERNAL_PERMISSION_RESULT = 200
<android.support.constraint.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/findImage"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Find image"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/imageUri"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:maxLines="1"
        android:text="File URI: N/A"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/findImage" />

    <Button
        android:id="@+id/loadImage"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Load image"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageUri" />

    <TextView
        android:id="@+id/loadInfo"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Load time: N/A"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loadImage" />

    <Button
        android:id="@+id/saveImage"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Save image"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/loadInfo" />

    <TextView
        android:id="@+id/saveInfo"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Save time: N/A"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/saveImage" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="9:16"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/saveInfo" />


</android.support.constraint.ConstraintLayout>

1 użytkowników online, w tym zalogowanych: 0, gości: 1