Analisis penuh peta bit (peta bit) Bahagian 1


Pengenalan kepada bahagian ini:

Dalam bahagian sebelumnya, kami telah menerangkan 13 jenis jenis Drawable dalam Android Adakah anda telah menggunakannya pada anda sendiri Bagaimana dengan projek? Dalam bahagian ini, kita akan membincangkan beberapa kegunaan Bitmap Sebelum memulakan kandungan bahagian ini, kita Mula-mula mari kita bezakan konsep beberapa kata nama:

  • Drawable: objek grafik umum, digunakan untuk memuatkan imej dalam format biasa, yang boleh menjadi imej seperti PNG dan JPG. Ia juga merupakan 13 objek visual jenis Drawable yang dipelajari sebelum ini! Kami boleh memahaminya sebagai tempat untuk meletakkan lukisan - bingkai gambar!
  • Bitmap: Kita boleh menganggapnya sebagai kuda kuda, kita meletakkan lukisan di atasnya dahulu, dan kemudian kita boleh Lakukan beberapa pemprosesan, seperti mendapatkan maklumat fail imej, melakukan putaran dan pemotongan, zum masuk dan keluar, dsb.!
  • Kanvas(kanvas): Seperti namanya, Kanvas, kami boleh melukis (melukis) padanya, anda boleh menggunakan sama ada Cat (berus) , Untuk melukis pelbagai bentuk atau menulis perkataan, anda juga boleh menggunakan Laluan (laluan) untuk melukis berbilang titik dan kemudian menyambungkannya ke dalam pelbagai bentuk!
  • Matriks (matriks): digunakan untuk pemprosesan kesan khas grafik, matriks warna (ColorMatrix) dan Matriks untuk pemprosesan imej Sorot, zum, putar, condongkan dan banyak lagi!

Di atas ialah kelas grafik asas dalam Android: android.graphics memberikan kami antara muka! Nah, tanpa berlengah lagi, mari mulakan bahagian ini! PS: Dokumen rasmi: Bitmap


1 Fahami Bitmap, BitmapFactory, BitmapFacotry.Options

Seperti tajuknya, saya boleh. telah mengatakannya secara langsung Tiga perkara itu berkaitan, tetapi saya hanya mahu menjadi tsundere dan saya perlu melihat kodnya! 1.gifJika anda membuka kod sumber kelas Bitmap, anda akan melihat sesuatu seperti ini dalam kaedah pembinaan Bitmap:

2.png

Apa yang saya mungkin ingin katakan ialah: struktur Bitmap Kaedah ini adalah peribadi dan tidak boleh digunakan di luar, hanya melalui JNI! Sudah tentu, kami pasti akan dibekalkan dengan antara muka untuk kami mencipta Bitmap, dan kelas antara muka ini ialah: BitmapFactory! Ayuh, buka kelas BitmapFactory Kami klik pada Structure di sebelah kiri untuk melihat yang BitmapFactory berikan kepada kami Kaedah ini disediakan, kebanyakannya adalah decodeXxx, untuk mencipta Bitmap dalam pelbagai bentuk!

3.png

Kemudian kami mendapati bahawa setiap kaedah mempunyai parameter jenis Pilihan, klik padanya untuk melihat: Jadi kami mendapati bahawa perkara ini ialah kelas dalaman statik: BitmapFacotry.Options! Dan dia digunakan untuk menetapkan pilihan semasa penyahkodan!

4.png

Kami menetapkan nilai beberapa parameter di sini, seperti menetapkan dalamJustDecodeBounds kepada benar untuk mengelakkan OOM (memori limpahan), Apa, saya tidak tahu OOM, tidak mengapa, saya akan menerangkannya kepada anda kemudian! Akhirnya kembali ke Bitmap kami! Nah, dalam Bitmap Terdapat banyak kaedah, jadi saya tidak akan menerangkannya satu persatu. Mari pilih beberapa yang digunakan lebih banyak dan terangkan! Dokumentasi Cina: Android Chinese API (136) - Bitmap


2. Bitmap kaedah biasa

Kaedah biasa

  • public boolean compress (Format Bitmap.CompressFormat, kualiti int, strim OutputStream) Memampatkan peta bit kepada OutputStream yang ditentukan boleh difahami sebagai menyimpan Peta Bit ke fail! format: format, PNG, JPG, dsb.; kualiti: kualiti mampatan, 0-100, 0 mewakili pemampatan kualiti terendah, 100 ialah kualiti maksimum (PNG adalah tanpa kerugian dan tetapan kualiti akan diabaikan) strim: strim output Nilai pulangan mewakili sama ada pemampatan berjaya ke aliran yang ditentukan!
  • void recycle(): Kitar semula ruang memori yang diduduki oleh bitmap dan tandai bitmap sebagai Dead
  • boolean is Recycled(): Judgment bit Sama ada memori imej telah dikeluarkan
  • int getWidth(): Dapatkan lebar peta bit
  • int getHeight(): Dapatkan ketinggian daripada peta bit
  • boolean isMutable(): Sama ada imej boleh diubah suai
  • int getScaledWidth(Kanvas kanvas): Dapatkan lebar imej selepas penukaran ketumpatan yang ditentukan
  • int getScaledHeight(Kanvas kanvas): Dapatkan ketinggian imej selepas penukaran ketumpatan yang ditentukan

Kaedah statik :

  • Bitmap createBitmap(Bitmap src): Gunakan src sebagai imej asal untuk menjana imej baharu yang tidak boleh diubah
  • Bitmap create(Bitmap src, int dstWidth, int dstHeight , penapis boolean): Gunakan src sebagai imej asal untuk mencipta imej baharu, nyatakan ketinggian dan lebar imej baharu dan sama ada hendak menukarnya.
  • Bitmap
  • createBitmap(int width, int height, Config config): Cipta bitmap dengan format dan saiz yang ditentukan
  • Bitmap
  • createBitmap(Sumber bitmap , int x, int y, int lebar, int height) mengambil sumber sebagai imej asal, mencipta imej baharu dan menentukan koordinat permulaan serta ketinggian dan lebar imej baharu.
  • Peta Bit statik awam
  • createBitmap(Sumber peta bit, int x, int y, lebar int, ketinggian int, Matriks m, penapis boolean)

BitmapFactory.OptionParameter boleh tetap:

  • boolean inJustDecodeBounds - Jika ditetapkan kepada benar, imej tidak akan diperoleh dan memori tidak akan diperuntukkan, tetapi maklumat ketinggian dan lebar imej akan dikembalikan.
  • int inSampleSize——Berbilang penskalaan imej. Jika ia ditetapkan kepada 4, maka lebar dan tinggi adalah 1/4 daripada saiz asal dan imej ialah 1/16 daripada saiz asal.
  • int outWidth——Dapatkan nilai lebar imej
  • int outHeight——Dapatkan nilai ketinggian imej
  • int inDensity - Nisbah mampatan piksel yang digunakan untuk peta bit
  • int inTargetDensity - Nisbah mampatan piksel yang digunakan untuk peta bit sasaran (peta bit yang akan dijana)
  • boolean inScaled - Pemampatan imej apabila ditetapkan kepada benar, daripada inDensity kepada inTargetDensity.

Baiklah, itu sahaja anda perlu menyemak sendiri dokumentasi~


3 Dapatkan Bitmap

Ada dua cara untuk mendapatkan peta bit daripada sumber: melalui BitmapDrawable atau BitmapFactory, seperti yang ditunjukkan di bawah: Mula-mula kita perlu mendapatkan ini

Kaedah BitmapDrawable:

Anda boleh mencipta pembina untuk membina objek BitmapDrawable, seperti membina BitmapDrawable melalui aliran:

BitmapDrawable bmpMeizi = new BitmapDrawable(getAssets().open("pic_meizi.jpg"));
Bitmap mBitmap = bmpMeizi.getBitmap();
img_bg.setImageBitmap(mBitmap);

Kaedah BitmapFactory:

adalah semua kaedah statik, yang boleh dipanggil terus Bitmaps boleh diperolehi melalui ID sumber, laluan, fail, aliran data, dsb. !

//通过资源ID
private Bitmap getBitmapFromResource(Resources res, int resId) {
      return BitmapFactory.decodeResource(res, resId);
}

//文件
private Bitmap getBitmapFromFile(String pathName) {
      return BitmapFactory.decodeFile(pathName);
}

//字节数组
public Bitmap Bytes2Bimap(byte[] b) {
    if (b.length != 0) {
        return BitmapFactory.decodeByteArray(b, 0, b.length);
    } else {
        return null;
    }
}

//输入流
private Bitmap getBitmapFromStream(InputStream inputStream) {
      return BitmapFactory.decodeStream(inputStream);
}

4 Dapatkan maklumat berkaitan Bitmap:

Ini, selagi kita mendapat objek Bitmap, kita boleh memanggil kaedah yang berkaitan untuk mendapatkan parameter yang sepadan, getByteCount mendapat saiznya. , getHeight dan getWidth ~ Saya tidak akan menulisnya di sini, semak dokumentasi sendiri!


5 Potong sudut tertentu pada gambar

Kadangkala, anda mungkin ingin menarik sudut tertentu gambar, hanya gunakan createBitmap() Bitmap untuk menariknya. Parameternya ialah: objek peta bit yang diproses, permulaan x, koordinat y, dan lebar dan tinggi yang dipintas

Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.mipmap.pic_meizi);
Bitmap bitmap2 = Bitmap.createBitmap(bitmap1,100,100,200,200);
img_bg = (ImageView) findViewById(R.id.img_bg);
img_bg.setImageBitmap(bitmap2);

Menjalankan rendering :

Imej asal:

5.png

Potong sudut:

6.png


6 Skalakan Peta Bit

7.png

Kami tidak menggunakan Matrix untuk membandingkan Bitmap di sini, tetapi terus menggunakan createScaledBitmap yang disediakan oleh Bitmap untuk melaksanakannya. Parameternya ialah: objek peta bit yang diproses, lebar dan tinggi berskala,


7 Gunakan Peta Bit untuk mengambil tangkapan skrin

Jalankan pemaparan :

< 🎜. >

8.gif

Kod pelaksanaan:

public class MainActivity extends AppCompatActivity {
    static ByteArrayOutputStream byteOut = null;
    private Bitmap bitmap = null;
    private Button btn_cut;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_cut = (Button) findViewById(R.id.btn_cut);
        btn_cut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                captureScreen();
            }
        });
    }

    public void captureScreen() {
        Runnable action = new Runnable() {
            @Override
            public void run() {
                final View contentView = getWindow().getDecorView();
                try{
                    Log.e("HEHE",contentView.getHeight()+":"+contentView.getWidth());
                    bitmap = Bitmap.createBitmap(contentView.getWidth(),
                            contentView.getHeight(), Bitmap.Config.ARGB_4444);
                    contentView.draw(new Canvas(bitmap));
                    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteOut);
                    savePic(bitmap, "sdcard/short.png");
                }catch (Exception e){e.printStackTrace();}
                finally {
                    try{
                        if (null != byteOut)
                            byteOut.close();
                        if (null != bitmap && !bitmap.isRecycled()) {
//                            bitmap.recycle();
                            bitmap = null;
                        }
                    }catch (IOException e){e.printStackTrace();}

                }
            }
        };
        try {
            action.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void savePic(Bitmap b, String strFileName) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(strFileName);
            if (null != fos) {
                boolean success= b.compress(Bitmap.CompressFormat.PNG, 100, fos);
                fos.flush();
                fos.close();
                if(success)
                    Toast.makeText(MainActivity.this, "截屏成功", Toast.LENGTH_SHORT).show();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Analisis kod:

Kod ini sangat mudah, View contentView akhir = getWindow().getDecorView(); Pandangan nod akar! Kemudian tetapkan saiz tangkapan skrin dan panggil contentView.draw(new Canvas(bitmap)); Peta bit ditukar menjadi strim, dan kemudian ditulis pada kad SD Ia hilang~ Sudah tentu, kita juga boleh melihat daripada hasil tangkapan skrin hanya menangkap kandungan APP yang diubah suai. Jika anda ingin menangkap skrin penuh, Google sendiri~!


Ringkasan bahagian ini:

Bahagian ini akan menerangkan kepada anda Bitmap, BitmapFactory dan Pilihan kelas dalaman statiknya, dan BitmapDrawable Untuk kegunaan asas, sebenarnya, kita hanya perlu tahu cara mencipta Bitmap secara umumnya dilaksanakan melalui Matrix dan Canvas. Bitmap, kami memberi perhatian lebih kepada masalah OOM Dalam bahagian seterusnya, kami akan belajar bagaimana untuk mengelakkan masalah OOM Bitmap! Terima kasih~9.gif