Saya mencari cara tercepat untuk mendapatkan data piksel (dalam bentuk int[][]
) dari a BufferedImage
. Tujuan saya adalah untuk dapat menangani piksel (x, y)
dari gambar menggunakan int[x][y]
. Semua metode yang saya temukan tidak melakukan ini (kebanyakan dari mereka mengembalikan int[]
).
java
bufferedimage
javax.imageio
ryyst
sumber
sumber
getRGB
dansetRGB
secara langsung?getRGB
dansetRGB
secara langsung.Jawaban:
Saya baru saja bermain-main dengan subjek yang sama ini, yang merupakan cara tercepat untuk mengakses piksel. Saat ini saya mengetahui dua cara untuk melakukan ini:
getRGB()
metode seperti yang dijelaskan dalam jawaban @ tskuzzy.Dengan mengakses larik piksel secara langsung menggunakan:
Jika Anda bekerja dengan gambar besar dan kinerja adalah masalah, metode pertama sama sekali bukan cara yang tepat. Itu
getRGB()
Metode menggabungkan alpha, merah, nilai-nilai hijau dan biru menjadi satu int dan kemudian mengembalikan hasil, yang dalam banyak kasus Anda akan melakukan hal yang sebaliknya untuk mendapatkan nilai-nilai ini kembali.Metode kedua akan mengembalikan nilai merah, hijau dan biru secara langsung untuk setiap piksel, dan jika ada saluran alfa akan menambahkan nilai alfa. Menggunakan metode ini lebih sulit dalam hal menghitung indeks, tetapi jauh lebih cepat daripada pendekatan pertama.
Dalam aplikasi saya, saya dapat mengurangi waktu pemrosesan piksel lebih dari 90% dengan hanya beralih dari pendekatan pertama ke yang kedua!
Berikut adalah perbandingan yang telah saya siapkan untuk membandingkan dua pendekatan:
Bisakah Anda menebak hasilnya? ;)
sumber
convertTo2DUsingGetRGB
danconvertTo2DWithoutUsingGetRGB
. Tes pertama rata-rata membutuhkan waktu 16 detik. Tes kedua rata-rata membutuhkan waktu 1,5 detik. Awalnya saya pikir "s" dan "ms" adalah dua kolom yang berbeda. @Mota, referensi bagus.BufferedImage
'stype
misalnyaTYPE_INT_RGB
atauTYPE_3BYTE_BGR
dan menangani dengan tepat. Ini adalah salah satu hal yang bermanfaatgetRGB()
bagi Anda, yang membuatnya lebih lambat :-(|=
daripada+=
menggabungkan nilai dalam metode 2?Sesuatu seperti ini?
sumber
BufferedImage
akan menyimpan piksel menggunakan array int 2D, sih?Raster
buffer data, yang tentunya merupakan hal yang baik karena menghasilkan akselerasi punting.Saya menemukan jawaban Mota memberi saya peningkatan kecepatan 10 kali lipat - jadi terima kasih Mota.
Saya telah membungkus kode dalam kelas yang nyaman yang mengambil BufferedImage di konstruktor dan mengekspos metode getRBG (x, y) yang setara yang menjadikannya sebagai pengganti kode menggunakan BufferedImage.getRGB (x, y)
sumber
Jawaban Mota sangat bagus kecuali BufferedImage Anda berasal dari Monochrome Bitmap. Bitmap Monokrom hanya memiliki 2 kemungkinan nilai untuk pikselnya (misalnya 0 = hitam dan 1 = putih). Ketika Monochrome Bitmap digunakan maka file
panggilan mengembalikan data mentah Pixel Array sedemikian rupa sehingga setiap byte berisi lebih dari satu piksel.
Jadi ketika Anda menggunakan gambar Monochrome Bitmap untuk membuat objek BufferedImage, berikut adalah algoritme yang ingin Anda gunakan:
sumber
Jika berguna, coba ini:
sumber
Berikut adalah implementasi FastRGB lain yang ditemukan di sini :
Apa ini?
Membaca gambar piksel demi piksel melalui metode getRGB BufferedImage cukup lambat, kelas ini adalah solusi untuk ini.
Idenya adalah Anda membuat objek dengan memberinya instance BufferedImage, dan itu membaca semua data sekaligus dan menyimpannya dalam array. Setelah Anda ingin mendapatkan piksel, Anda memanggil getRGB
Dependensi
Pertimbangan
Meskipun FastRGB membuat piksel membaca jauh lebih cepat, itu dapat menyebabkan penggunaan memori yang tinggi, karena hanya menyimpan salinan gambar. Jadi, jika Anda memiliki BufferedImage 4MB di memori, setelah Anda membuat instance FastRGB, penggunaan memori akan menjadi 8MB. Namun, Anda dapat mendaur ulang instance BufferedImage setelah Anda membuat FastRGB.
Berhati-hatilah agar tidak jatuh ke OutOfMemoryException saat menggunakannya di perangkat seperti ponsel Android, di mana RAM menjadi penghambat
sumber
Ini berhasil untuk saya:
sumber
i
?