Analyse complète Bitmap (bitmap) Partie 1


Introduction à cette section :

Dans la section précédente, nous avons expliqué les 13 types de types Drawable dans Android. Les avez-vous appliqués aux vôtres. Et les projets ? Dans cette section, nous aborderons certaines utilisations de Bitmap. Avant de commencer le contenu de cette section, nous Distinguons d'abord les concepts de plusieurs noms :

  • Drawable : un objet graphique général, utilisé pour charger des images dans des formats courants, qui peuvent être des images telles que PNG et JPG. Ce sont aussi les 13 objets visuels de type Drawable appris plus tôt ! On peut le comprendre comme un endroit pour placer des tableaux - cadre photo !
  • Bitmap : On peut le considérer comme un chevalet, on met d'abord la peinture dessus, et ensuite on peut Effectuez certains traitements, tels que l'obtention d'informations sur le fichier image, la rotation et la découpe, le zoom avant et arrière, etc. !
  • Toile(toile) : Comme son nom l'indique, Toile, on peut peindre (dessiner) dessus, vous pouvez soit utiliser Peinture (pinceau) , Pour dessiner diverses formes ou écrire des mots, vous pouvez également utiliser Chemin (chemin) pour dessiner plusieurs points, puis les relier en différentes formes !
  • Matrix (matrix) : utilisé pour le traitement des effets spéciaux graphiques, la matrice de couleurs (ColorMatrix) et Matrix pour le traitement de l'image Panoramique, zoom, rotation, inclinaison et bien plus encore !

Ce qui précède sont les classes graphiques sous-jacentes dans Android : android.graphics nous fournit l'interface ! Eh bien, sans plus tarder, commençons cette section ! PS : Documents officiels : Bitmap


1 Comprendre Bitmap, BitmapFactory, BitmapFacotry.Options

Comme le titre l'indique, je pourrais. Je l'ai dit directement. Les trois choses sont liées, mais je veux juste être tsundere et je dois regarder le code ! 1.gifSi vous ouvrez le code source de la classe Bitmap, vous verrez quelque chose comme ceci dans la méthode de construction de Bitmap :

2.png

Ce que je veux probablement dire, c'est : la structure de Bitmap La méthode est privée et ne peut pas être instanciée à l'extérieur, uniquement via JNI ! Bien sûr, nous aurons certainement une interface pour créer du Bitmap, et cette classe d'interface est : BitmapFactory ! Allez, ouvrez la classe BitmapFactory. On clique sur la Structure à gauche pour voir que BitmapFactory nous donne. Ces méthodes sont fournies, dont la plupart sont decodeXxx, pour créer des Bitmap sous diverses formes !

3.png

Puis nous avons découvert que chaque méthode possède un paramètre de type Options, cliquez dessus pour y jeter un oeil : Nous avons donc découvert que cette chose est une classe interne statique : BitmapFacotry.Options ! Et il sert à paramétrer les options lors du décodage !

4.png

Nous définissons ici les valeurs​​de certains paramètres, comme la définition de inJustDecodeBounds sur true pour éviter le MOO (débordement de mémoire), Quoi, je ne sais pas OOM, c'est bon, je t'expliquerai plus tard ! Revenons enfin à notre Bitmap ! Eh bien, en Bitmap Il existe de nombreuses méthodes, je ne vais donc pas les expliquer une par une. Choisissons-en quelques-unes qui sont les plus utilisées et expliquons-les ! Documentation chinoise : API chinoise Android (136) - Bitmap


Méthodes courantes Bitmap

Méthodes courantes< 🎜. >

    booléen public
  • compress (format Bitmap.CompressFormat, qualité int, flux OutputStream) Compresser le bitmap dans le OutputStream spécifié peut être compris comme enregistrer le Bitmap dans un fichier ! format : format, PNG, JPG, etc. ; qualité : qualité de compression, 0-100, 0 représente la qualité de compression la plus basse, 100 est la qualité maximale (PNG est sans perte, et les paramètres de qualité seront ignorés) stream : flux de sortie La valeur de retour indique si la compression a réussi pour le flux spécifié !
  • void
  • recycle() : recycle l'espace mémoire occupé par le bitmap et marque le bitmap comme Dead
  • booléen
  • isRecycled() : bit de jugement Si la mémoire de l'image a été libérée
  • int
  • getWidth() : Obtenez la largeur du bitmap
  • int
  • getHeight() : Obtenez la hauteur du bitmap
  • boolean
  • isMutable() : indique si l'image peut être modifiée
  • int
  • getScaledWidth(Canvas Canvas) : obtient la largeur du bitmap image après la conversion de densité spécifiée
  • int
  • getScaledHeight(Canvas Canvas) : obtenez la hauteur de l'image après la conversion de densité spécifiée

Méthode statique  :

    Bitmap
  • createBitmap(Bitmap src) : utilisez src comme image originale pour générer une nouvelle image immuable
  • Bitmap
  • createScaledBitmap(Bitmap src, int dstWidth, int dstHeight , boolean filter) : utilisez src comme image d'origine pour créer une nouvelle image, spécifiez la hauteur et la largeur de la nouvelle image et si vous souhaitez la modifier.
  • Bitmap
  • createBitmap(int width, int height, Config config) : Créer un bitmap du format et de la taille spécifiés
  • Bitmap
  • createBitmap(Source du bitmap , int x, int y, int largeur, int height) prend la source comme image d'origine, crée une nouvelle image et spécifie les coordonnées de départ ainsi que la hauteur et la largeur de la nouvelle image.
  • Bitmap statique public
  • createBitmap(Source du bitmap, int x, int y, int largeur, int hauteur, Matrice m, filtre booléen)

BitmapFactory.OptionParamètres réglables :

  • boolean inJustDecodeBounds - Si défini sur true, l'image ne sera pas obtenue et la mémoire ne sera pas allouée, mais les informations de hauteur et de largeur de l'image seront renvoyées.
  • int inSampleSize——Le multiple de la mise à l'échelle de l'image. S'il est défini sur 4, alors la largeur et la hauteur correspondent toutes deux à 1/4 de la taille d'origine et l'image à 1/16 de la taille d'origine.
  • int outWidth——Obtenir la valeur de largeur de l'image
  • int outHeight——Obtenir la valeur de hauteur de l'image
  • int inDensity - Taux de compression des pixels utilisé pour le bitmap
  • int inTargetDensity - Taux de compression des pixels utilisé pour le bitmap cible (le bitmap à générer)
  • booléen inScaled - Compression d'image lorsqu'elle est définie sur true, de inDensity à inTargetDensity.

D'accord, c'est tout. Vous devez vérifier la documentation vous-même~


3 Obtenez le Bitmap

Il y en a. deux manières d'obtenir des bitmaps à partir de ressources : via BitmapDrawable ou BitmapFactory, comme illustré ci-dessous : Nous devons d'abord obtenir ceci

Méthode BitmapDrawable :

Vous pouvez créer un constructeur pour construire un objet BitmapDrawable, par exemple en construisant un BitmapDrawable via un flux :

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

Méthodes BitmapFactory :

sont toutes des méthodes statiques, qui peuvent être appelées directement. Les bitmaps peuvent être obtenus via l'ID de ressource, le chemin, le fichier, le flux de données, etc. !

//通过资源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. Obtenir les informations relatives au Bitmap :

Ceci, tant que nous obtenons l'objet Bitmap, nous pouvons appeler la méthode appropriée pour obtenir les paramètres correspondants, getByteCount obtient la taille. , getHeight et getWidth ~ Je ne les écrirai pas ici, vérifiez vous-même la documentation !


5. Coupez un certain coin de l'image

Parfois, vous souhaiterez peut-être retirer un certain coin de l'image, utilisez simplement createBitmap() de Bitmap pour le retirer. Les paramètres sont : l'objet bitmap traité, les coordonnées x et y de départ et la largeur et la hauteur interceptées

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);

Rendu en cours d'exécution  :

Image originale :

5.png

Coupez le coin :

6.png


6. Redimensionnez le bitmap

7.png

Nous n'utilisons pas Matrix pour comparer Bitmap ici, mais utilisons directement le createScaledBitmap fourni par Bitmap pour l'implémenter. Les paramètres sont : objet bitmap traité, largeur et hauteur mises à l'échelle,


7. Utilisez Bitmap pour prendre des captures d'écran

Exécutez le rendu  :

8.gif

Code d'implémentation:

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();
        }
    }
}

Analyse du code:

Le code est très simple, final View contentView = getWindow().getDecorView(); Vue du nœud racine ! Définissez ensuite la taille de la capture d'écran et appelez contentView.draw(new Canvas(bitmap)); Le bitmap est converti en flux, puis écrit sur la carte SD. C'est parti ~ Bien sûr, nous pouvons également voir d'après les résultats que la capture d'écran ne capture que le contenu de l'APP modifiée ! Si vous souhaitez capturer le plein écran, recherchez-le vous-même sur Google~ !


Résumé de cette section :

Cette section vous expliquera Bitmap, BitmapFactory et ses options de classe interne statique et BitmapDrawable Pour une utilisation basique, en effet, il suffit de savoir créer Bitmap. Son extension est généralement implémentée via Matrix et Canvas. Bitmap, nous accordons plus d'attention au problème du MOO. Dans la section suivante, nous apprendrons comment éviter le problème du MOO de Bitmap ! Merci~9.gif