What is bitmap in Android?
![]()
Hey! Welcome to my article Dear Android Developers! and Dear Predators!
Today, we are going to discuss Bitmap. Most developers accept the concept of Bitmap as an image, but the issue is completely different. So, what is it?
The definition comes from its own name(Bit-map). Therefore, Bitmap represents pixel that we can draw something on the screen(or on coordinate system).
For instance, In this example we created a 100 by 100 pixel bitmap.
Furthermore, We can convert image files into bitmap objects. Likewise, it is possible to transform in the opposite way.
Or, we can set our image like a bitmap.
In addition, we can easily create a custom view using the bitmap. Check out my other article for more information on custom view!
Класс Bitmap
Вам часто придётся иметь дело с изображениями котов, которые хранятся в файлах JPG, PNG, GIF. По сути, любое изображение, которое мы загружаем из графического файла, является набором цветных точек (пикселей). А информацию о каждой точке можно сохранить в битах. Отсюда и название — карта битов или по-буржуйски — bitmap. У нас иногда используется термин растр или растровое изображение. В Android есть специальный класс android.graphics.Bitmap для работы с подобными картинками.
Существуют готовые растровые изображения в файлах, о которых поговорим ниже. А чтобы создать с нуля объект Bitmap программным способом, нужно вызвать метод createBitmap():
В результате получится прямоугольник с заданными размерами в пикселях (первые два параметра). Третий параметр отвечает за информацию о прозрачности и качестве цвета (в конце статьи есть примеры).
Очень часто нужно знать размеры изображения. Чтобы узнать его ширину и высоту в пикселах, используйте соответствующие методы:
Bitmap.Config
Кроме размеров, желательно знать цветовую схему. У класса Bitmap есть метод getConfig(), который возвращает перечисление Bitmap.Config.
Всего существует несколько элементов перечисления.
- Bitmap.Config ALPHA_8 — каждый пиксель содержит в себе информацию только о прозрачности, о цвете здесь ничего нет. Каждый пиксель требует 8 бит (1 байт) памяти.
- Bitmap.Config ARGB_4444 — устаревшая конфигурация, начиная с API 13. Аналог ARGB_8888, только каждому ARGB-компоненту отведено не по 8, а по 4 бита. Соответственно пиксель весит 16 бит (2 байта). Рекомендуется использовать ARGB_8888
- Bitmap.Config ARGB_8888 — на каждый из 4-х ARGB-компонентов пикселя (альфа, красный, зеленый, голубой) выделяется по 8 бит (1 байт). Каждый пиксель занимает 4 байта. Обладает наивысшим качеством для картинки.
- Bitmap.Config RGB_565 — красному и и синему компоненту выделено по 5 бит (32 различных значений), а зелёному — шесть бит (64 возможных значений). Картинка с такой конфигурацией может иметь артефакты. Каждый пиксель будет занимать 16 бит или 2 байта. Конфигурация не хранит информацию о прозрачности. Можно использовать в тех случаях, когда рисунки не требуют прозрачности и высокого качества.
Конфигурация RGB_565 была очень популярна на старых устройствах. С увеличением памяти и мощности процессоров данная конфигурация теряет актуальность.
В большинстве случаев вы можете использовать ARGB_8888.
Получив объект в своё распоряжение, вы можете управлять каждой его точкой. Например, закрасить его синим цветом.
Чтобы закрасить отдельную точку, используйте метод setPixel() (парный ему метод getPixel позволит узнать информацию о точке). Закрасим красной точкой центр синего прямоугольника из предыдущего примера — имитация следа от лазерной указки. Котам понравится.
В нашем случае мы создали растровое изображение самостоятельно и можем на него воздействовать. Но если вы загрузите готовое изображение из файла и попытаетесь добавить к нему красную точку, то можете получить крах программы. Изображение может быть неизменяемым, что-то типа «Только для чтения», помните об этом.
Созданный нами цветной прямоугольник и управление отдельными точками не позволят вам нарисовать фигуру, не говоря уже о полноценном рисунке. Класс Bitmap не имеет своих методов для рисования, для этого есть метод Canvas (Холст), на котором вы можете размещать объекты Bitmap.
Когда вы размещали в разметке активности компонент ImageView и присваивали атрибуту android:src ресурс из папок drawable-xxx, то система автоматически выводила изображение на экран.
Если нужно программно получить доступ к битовой карте (изображению) из ресурса, то используется такой код:
Обратный процес конвертации из Bitmap в Drawable:
Изображение можно сохранить, например, на SD-карту в виде файла (кусок кода):
Каждая точка изображения представлена в виде 4-байтного целого числа. Сначала идёт байт прозрачности — значение 0 соответствует полной прозрачности, а 255 говорит о полной непрозрачности. Промежуточные значения позволяют делать полупрозрачные изображения. Этим искусством в совершенстве владел чеширский кот, который умело управлял всеми точками своего тела и растворялся в пространстве, только улыбка кота долго ещё висела в воздухе (что-то я отвлёкся).
Следующие три байта отвечают за красный, зелёный и синий цвет, которые работают по такому же принципу. Т.е. значение 255 соответствует насыщенному красному цвету и т.д.
Так как любое изображение кота — это набор точек, то с помощью метода getPixels() мы можем получить массив этих точек, сделать с этой точкой что-нибудь нехорошее (поменять прозрачность или цвет), а потом с помощью родственного метода setPixels() записать новые данные обратно в изображение. Так можно перекрасить чёрного кота в белого и наоборот. Если вам нужна конкретная точка на изображении, то используйте методы getPixel()/setPixel(). Подобный подход используется во многих графических фильтрах. Учтите, что операция по замене каждой точки в большом изображении занимает много времени. Желательно проводить подобные операции в отдельном потоке.
На этом базовая часть знакомства с битовой картой закончена. Теперь подробнее.
Учитывая ограниченные возможности памяти у мобильных устройств, следует быть осторожным при использовании объекта Bitmap во избежание утечки памяти. Не забывайте освобождать ресурсы при помощи метода recycle(), если вы в них не нуждаетесь. Например:
Почему это важно? Если не задумываться о ресурсах памяти, то можете получить ошибку OutOfMemoryError. На каждое приложение выделяется ограниченное количество памяти (heap size), разное в зависимости от устройства. Например, 16мб, 24мб и выше. Современные устройства как правило имеют 24мб и выше, однако это не так много, если ваше приложение злоупотребляет графическими файлами.
Bitmap на каждый пиксель тратит в общем случае 2 или 4 байта (зависит от битности изображения – 16 бит RGB_555 или 32 бита ARGB_888). Можно посчитать, сколько тратится ресурсов на Bitmap, содержащий изображение, снятое на 5-мегапиксельную камеру.
При соотношении сторон 4:3 получится изображение со сторонами 2583 х 1936. В конфигурации RGB_555 объект Bitmap займёт 2592 * 1936 * 2 = около 10Мб, а в ARGB_888 (режим по умолчанию) в 2 раза больше – чуть более 19Мб.
Во избежание проблем с памятью прибегают к помощи методов decodeXXX() класса BitmapFactory.
Если установить атрибут largeHeap в манифесте, то приложению будет выделен дополнительный блок памяти.
Ещё одна потенциальная проблема. У вас есть Bitmap и присвоили данный объект кому-то. Затем объект был удалён из памяти, а ссылка на него осталась. Получите крах приложения с ошибкой типа «Exception on Bitmap, throwIfRecycled».
Возможно, лучше сделать копию.
Получить Bitmap из ImageView
Если в ImageView имеется изображение, то получить Bitmap можно следующим образом:
Но с этим способом нужно быть осторожным. Например, если в ImageView используются элементы LayerDrawable, то возникнет ошибка. Можно попробовать такой вариант.
Более сложный вариант, но и более надёжный.
Изменение размеров — метод createScaledBitmap()
С помощью метода createScaledBitmap() можно изменить размер изображения.
Будем тренироваться на кошках. Добавим картинку в ресурсы (res/drawable). В разметку добавим два элемента ImageView

В последнем параметре у метода идёт булева переменная, отвечающая за сглаживание пикселей. Обычно его применяют, когда маленькое изображение увеличивают в размерах, чтобы улучшить качество картинки. При уменьшении, как правило, в этом нет такой необходимости.
Кадрирование — метод createBitmap()
Существует несколько перегруженных версий метода Bitmap.createBitmap(), с помощью которых можно скопировать участок изображения.
- сreateBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) — Returns an immutable bitmap from subset of the source bitmap, transformed by the optional matrix.
- createBitmap(int width, int height, Bitmap.Config config) — Returns a mutable bitmap with the specified width and height.
- createBitmap(Bitmap source, int x, int y, int width, int height) — Returns an immutable bitmap from the specified subset of the source bitmap.
- createBitmap(int[] colors, int offset, int stride, int width, int height, Bitmap.Config config) — Returns a immutable bitmap with the specified width and height, with each pixel value set to the corresponding value in the colors array.
- createBitmap(Bitmap src) — Returns an immutable bitmap from the source bitmap.
- createBitmap(int[] colors, int width, int height, Bitmap.Config config) — Returns a immutable bitmap with the specified width and height, with each pixel value set to the corresponding value in the colors array.
Описываемый ниже код не является оптимальным и очень ресурсоёмкий. На больших изображениях код будет сильно тормозить. Приводится для ознакомления. Чтобы вывести часть картинки, можно сначала создать нужный Bitmap с заданными размерами, занести в массив каждый пиксель исходного изображения, а затем этот же массив вернуть обратно. Но, так как мы уже задали другие размеры, то часть пикселей не выведутся.
По аналогии мы можем вывести и нижнюю правую часть изображения:


Немного модифицировав код, мы можем кадрировать центр исходного изображения. Предварительно придётся проделать несколько несложных вычислений.
Скриншот приводить не буду, проверьте самостоятельно.
Меняем цвета каждого пикселя
Через метод getPixels() мы можем получить массив всех пикселей растра, а затем в цикле заменить определённым образом цвета в пикселе и получить перекрашенную картинку. Для примера возьмем стандартный значок приложения, поместим его в ImageView, извлечём информацию из значка при помощи метода decodeResource(), применим собственные методы замены цвета и полученный результат поместим в другие ImageView:
Код для класса активности:
На скриншоте представлен оригинальный значок и три варианта замены цветов.

Ещё один пример, где также в цикле меняем цвет каждого пикселя Green->Blue, Red->Green, Blue->Red (добавьте на экран два ImageView):
Конвертируем Bitmap в байтовый массив и обратно
Сжимаем картинку
В предыдущем примере вызывался метод compress(). Несколько слов о нём. В первом аргументе передаём формат изображения, поддерживаются форматы JPEG, PNG, WEBP. Во втором аргументе указываем степень сжатия от 0 до 100, 0 — для получения малого размера файла, 100 — максимальное качество. Формат PNG не поддерживает сжатие с потерей качества и будет игнорировать данное значение. В третьем аргументе указываем файловый поток.
Как раскодировать Bitmap из Base64
Если изображение передаётся в текстовом виде через Base64-строку, то воспользуйтесь методом, позволяющим получить картинку из этой строки:
Вычисляем средние значения цветов
Дополнительные материалы
На StackOverFlow есть интересный пример программной генерации цветных квадратов с первой буквой слова. В пример квадрат используется как значок к приложению. Также популярен этот приём в списках. Квадраты также заменять кружочками.
Introduction
The bitmap is used in many cases of massive data processing. Some typical situations include data filtering, data bit setting and statistics. Its introduction and application usually take into account the case of massive data, using ordinary arrays will exceed the scope of data storage. Although using this bitmap method cannot fundamentally solve the problem of massive data processing, it is an effective method within a certain range of data. Bitmap has a corresponding implementation in the java class library: BitSet. We will give an introduction to the introduction of bitmap, and then analyze in detail the subtle implementation of a bitvector, and compare it with the BitSet implementation in java later. In this article, no distinction is made between bitmap and bitvector, they express the same meaning.
The introduction of bitmap
Suppose we have a large data set, such as a set of numbers, which is stored in a large file. Its total number is 40 billion. There are a lot of repeated data, if the repeated elements are removed, the approximate data is 4 billion. So, suppose we have a machine with 2GB of RAM. How can we eliminate the repeated elements? Further consider, if we eliminate the repeated elements, how to count the number of elements in it and save the deduplicated elements to another result file?
Let us first make a rough estimate. Assume that the range of numbers is from 0 to Integer.MAX_VALUE. If we open an array to save, is it feasible? An int number is 4 bytes, if you want to store 0 to Integer.MAX_VALUE numbers, you need 2 to the 31st power, that is, 2G elements. Multiplying this way, unless you have 8GB of memory, you can’t save so much data at all.
Bitmap analysis and application
Now, what if we try another way and use bitmap? Bitmap is also an array in essence, but uses the corresponding bit in the middle of the array to represent a corresponding number. Suppose we use byte arrays. For example, the number 1 corresponds to the first position of the first element of the array. The number 9 is beyond the 8-bit range of the first element, and it corresponds to the first bit of the second element. By analogy, we can map these 4 billion elements to this byte array. The relationship between a number and the position in the array is shown in the following figure:

In the above figure, assuming that i is a byte in the array, it will correspond to the following 8 bits. Assuming that i is the first byte, then the number 1 corresponds to the first bit, and the following elements are in turn.
Through this discussion, we can also easily get the relationship between the number and the specific bits of the elements stored in the array. Suppose there is a number i, which corresponds to the saved element position: i / 8. If the array is a, then it is a[i/8]. So which bit does it correspond to in the middle of a[i/8]? It corresponds to the i% 8th position in this element.
With these discussions, let’s look at a specific implementation of bitmap.
An implementation of bitmap
Regarding the previous discussion, the main functions of bitmap include the following aspects.
1. Set: Set a certain position to 1.
2. Clear bit (clear), clear a bit, set it to 0.
3. Read the bit (get), read the data of a certain bit, and see if the result is 1 or 0.
4. The number of bits that the container can hold (size) is equivalent to the length of the returned container.
5. The number of elements set (count), and the number of all bits set to 1.
Let’s analyze one by one:
First of all, we have to define a byte array to store these data. In addition, we also need elements to store the number of bits in it and the number of elements that are set. Therefore, we have the following definition:
Now, suppose we want to construct a BitVector, we need to specify its length. One of its constructors can be constructed as follows:
Here, the specified parameter n indicates how many numbers there are, which is equivalent to how many bits need to be set. Since we want to save by byte, the number of bytes that can save so many numbers is n / 8 + 1. This length is expressed by shifting it as (size >> 3) + 1. Shifting 3 places to the right is equivalent to dividing by 8.
As mentioned earlier, to set an element of a bit, you need to find the byte where the element is located, and then set the bit corresponding to the byte. And n / 8 is the index of the corresponding byte, and n% 8 is the bit in the corresponding byte. The code implementation of this part is as follows:
Similar to what I discussed earlier, here is just the use of displacement to achieve the same effect. The front bit >> 3 is equivalent to bit / 8. And bit & 7 is equivalent to bit% 8. Why is bit & 7 equivalent to this effect? In frontAn article analyzing the implementation of HashMapThis technique has also been discussed here. Because a byte here is 8 bits, and the binary representation of 8 is 1000, then the binary form of 7 which is 1 smaller than it is 0111. When performing the AND operation between bit and 7, all high bits greater than the 3rd bit are set to 0, and the lowest 3 bits are reserved. In this way, the lowest 3 digits are 0 at the smallest and 7 at the largest. It is equivalent to the calculation effect of modulo the number 8.
clear
Contrary to the previous set method, here it is necessary to set the specific position to 0.
The code of the get part is mainly to determine whether this bit is set to 1. We add this byte and the number whose corresponding bit is 1. If the result is not 0, it means it is set to 1.
count
The realization of the count method is a more subtle technique. According to our original understanding, if we want to calculate the number of bits set to 1, we need to traverse each byte, and then find the number of 1s in each byte. One way to take it for granted is to perform an AND operation with the number shifted by number 1. If the result is 0, it means that the bit is not set to 1, otherwise it means that the bit is set. This method is no problem, but if you have to go through this round for each byte, it is equivalent to 8 times the previous calculation. If we can optimize it, there is still some value for big data. The following is an implementation of another efficient method, using space for time:
An array of BYTE_COUNTS is created here. It records the number corresponding to a number 1. What we get after the bit[i] && 0xff operation is an 8-bit number ranging from 0 to 255. Then, the problem comes down to finding the number of 1s in the binary representation of the corresponding number. For example, the number 0 has 0 1s, 1 has 1 1, 2 has 1 1, 3 has 2 1s. In a byte, there are up to 256 types. If we encode and save the number corresponding to these 256 numbers in advance, we can find the number corresponding to this number later and just take it directly.
Comparison with BitSet
The implementation of bitmap we discussed earlier is actually taken from open source softwareluceneCode snippets. It uses byte arrays as a method of internal data storage. Various setting operations and calculations use binary shift and other operations to achieve the highest possible efficiency. In Java’s internal class library, there is actually a similar implementation. That is BitSet.
The internal implementation of BitSet is slightly different from that of BitVector. It internally uses a long[] array to store elements. In this way, there is a difference between each set and clear operation. For example, setting a bit. Originally, the number to be set was divided by 8. Now it is divided by 64, which is equivalent to the operation of shifting 6 times in >> 6.
In addition, there is no implementation in BigSet to find the number of all elements that are set to 1. If they are required, because they need to be found in the 64-bit number range, it is impossible to use the previous number list method to speed up the statistics. The speed can only be calculated and compared statistics bit by bit. This is a shortcoming of this implementation.
There is another interesting part of BitSet’s internal code implementation. Let’s look at this code first:
This is the corresponding setting method in java. According to our understanding, it should find the corresponding long element, and then set the corresponding bit after modulo 64 to 1. But the setting part in this code is as follows: words[wordIndex] |= (1L << bitIndex ); // Restores invariants. Shift is used here, but 64 is not modulated. why? Doesn’t it go wrong? In our understanding, if the number is shifted to the left, if it exceeds the range of the number, it will subconsciously think that those parts are ignored. If you think about it this way, won’t you get a 0 after such a shift? We will continue to analyze this point later.
An interesting place
The answer to this question is not complicated. If we look at the definition in the book, we will find it after a closer look. << >> and other such shift operations are actually cyclic shift effects. In other words, if I shift a number to the left to overflow, it will not be ignored, but will continue to be filled in the lower bits. For example, let’s look at the simplest code below:
If we execute the above piece of code, we will find that the actual result is that when it overflows, it starts to display from the beginning. Part of the output result is as follows:
Now, we also understand why a left shift operation is used directly in the front. Because this is a cyclic shift, it is equivalent to the effect of modulo calculation. To be honest, this method is feasible, but I don’t think it is intuitive, so it is better to use a method similar to modulo operation.
to sum up
The bitmap expresses the presence or absence of data by making full use of the setting of each bit in the array. For example, if a bit is set to 1, it means that the data exists, otherwise it means it does not exist. By making full use of the data space, it has a higher space utilization rate than directly using an array, and then each element in the array represents an array. For example, there is an int array of the same length. Originally, an int element was used to represent a piece of data. Now using each bit of the int element, it can represent 32 elements. Therefore, to a certain extent, some data mapping, filtering and other issues can be handled by bitmap in a larger range. Of course, bitmap is also limited by the range of data representation of the computer itself. After a certain range is exceeded, we still need to consider methods such as combining data division. In addition, when considering the detailed implementation of these data structures, there are many details that will deepen our understanding, and perhaps many of them are what we usually ignore.
Bitmap in android a tutorial ?
A bitmap is an object , which is an instance of the Bitmap Class. This class represents a 2d coordinate system . The coordinate system move to the right on the x axis , and to the bottom on the y axis .
Each point in the coordinate system is called a pixel . A pixel is formed of bits , and bits represent the color of this pixel. A pixel can be formed of 8 , or 16 or 24 bits … The x axis represents the width , and the y axis represent the height .

Everything that is drawn in android is a Bitmap . We can create a Bitmap instance , either by using the Bitmap class which has methods that allow us to manipulate pixels in the 2d coordinate system , or we can can create a Bitmap from an image or a file or a resource by using the BitmapFactory class
What is canvas ?
A canvas is an object which is an instance of the class Canvas . A canvas is used to draw on a bitmap , it has methods to draw shapes on a bitmap . Such as drawing a text , a line , a rectangle or a circle .. We can style the shapes created by the canvas by using a paint object .
What is paint ?
A paint object is an instance of the Paint class . it is used to style a shape drawn by a canvas . We can set the stroke , the fill color .. of the drawn shape using the paint object.
Create a bitmap by using Bitmap class
The Bitmap class has many methods that allow us to create an instance of a Bitmap by using java . These methods will allow us to set the width , height , density , and number of pixels of a Bitmap .
Bitmap.createBitmap(int width, int height, Bitmap.Config config)
This method will take as parameters the width and height of the bitmap in pixels. It also takes the configuration for this Bitmap. The configuration specify the number of bits that each pixel in the bitmap will have. For example , we can specify that a pixel will take 32 bits (ARGB_8888) , as such each red , green , blue color will take 8 bits , and the alpha channel will take 8 bits .


Bitmap.createBitmap(Bitmap src)
we can use this method to get a copy of a Bitmap that is already created .
- If the source Bitmap is immutable return the source Bitmap
- if it is mutable , create a copy of the src Bitmap , and return it .

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height)
This method allow us to create a copy of a Bitmap .
- x,y are the coordinate of the first pixel in the source
- width is the number of pixel in the source, must be less or equal to sourceWidth-x
- height is the number of row in the source, must be less than sourceHeight-y
if x,y is 0 , 0 , and width and height equals the source bitmap width and height , and the source bitmap is immutable , return the source bitmap itself , else , return a copy of the source bitmap (x,y) , with the given width and height .

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height,Matrix m, boolean filter)
create a new Bitmap , from a source bitmap .
- x,y are the coordinate of the first pixel in the source
- width is the number of pixel in the source, must be less or equal to sourceWidth-x
- height is the number o row in the source, must be less or equal to sourceHeight-y
- m , is the transformation matrix . It contains, the operations that we can perform on a bitmap :
- translation : will translate a bitmap from old origin (0,0) , to new origin . This doesn’t work while creating a bitmap from another bitmap
- scaling
- skewing
- rotation
- if we want to perform just one operation , we can create a new matrix , and use the set methods, like setScale , setSkew ..
- if we want to perform multiple operations , we can create a new matrix , and use the pre and post methods . pre means the operation will be performed first , post means the operation will be performed after.
If the source x,y is 0,0 , and if the width and height is equal to the source width and height , and if the transformation matrix is the identity matrix , so if there is no transformation done , and if the source is immutable return the bitmap itself. Else , create a copy of the bitmap from the source (x,y), with the given width and height ,and transformation and filtering applied .
Translate
the translate methods
doesn’t work when create a bitmap from another one .

Rotate
the rotate methods ,
will rotate all pixels inside a bitmap clockwise by a given angle . The angle is specified in degree , and the point of rotation is the upper left corner which has a coordinate of (0,0) . The formula for rotation is

scale
we can use the scale methods
in order to scale the coordinate of an image up or down. The scaling is performed from the upper left corn which has a coordinate (0,0). When scaling up , we are creating new pixels , the new pixels are created by using linear interpolation . When scaling down we are removing pixels using sampling . We can set set the filter option to true in both cases , to create smoother images . If the x and y scale factor are equal , the scaled image will keep its aspect ration . The formula for the scaled pixels is

skewing will skew all pixels using the following formula
A pixel has an (x ; y) coordinate , the new coordinate of the pixel are calculated using the formula (x + sx * y ; sy * x + y) . So x is moved from the y axis by a distance , and y is moved from the x axis by a distance .
The skew methods that we can use are

create a density independent bitmap
When we are creating a bitmap with the previous methods , we are specifying the width and height in pixel . Different screens have different densities , as such the width and height specified in pixel , will look different on different screens . we can create a bitmap by using density independent pixel , like this the bitmap will look similar on screens with different densities .

Create a bitmap using BitmapFactory
The BitmapFactory method allow us to create a Bitmap from a an array of bytes , or from a file or from a resource , or from an input stream.
BitmapFactory.decodeByteArray(byte[] data, int offset, int length, BitmapFactory.Options opts)
The decodeByteArray methods allow us to decode a Bitmap from a byte array . It takes as parameters :
- the byte array , that we want to decode into a Bitmap
- the offset which is where we want to start decoding.
- the length , which is the number of bytes that we want to decode
- the opts which is an instance of the Options class , and it is used to set the options that we want to use when decoding the byte array. If we pass null , it is as if we have create an instance of the Options class and passed it , so it is as if we have passed the default Option parameter . Some of the options that we can set are :
- inSampleSize , which is used to sample the image. We can useit , if we want to create a smaller image , so to sample down this image . the sampling parameter is specified in multiples of two , so 2 , 4 .. and the resulting size will be divided by this multiple of two . so if the original image is 20 by 50 , and sampling is two , the resulting image is 10 by 25.
- inMutable : if we want the returned Bitmap to be mutable , we can set this option to True.
- inDensity : is used to specify the density of the image in the byte array .
- inScaled : if set to true , android will scale the decoded image from the inDensity , to the screen Density where the application is running . so The decoded Bitmap might be scaled up or down.

BitmapFactory.decodeFile(String pathName, Options opts)
We can use this method in order to decode a Bitmap which is stored inside a file . The file location is specified as a string . This method takes two parameters
- pathName : a string specifying the file location
- opts : the option when decoding the file
Bitmap.decodeResource(Resources res, int id, BitmapFactory.Options opts)
we can use this method in order to decode a Bitmap which is stored inside the res folder . The res folder , is used to store bitmaps , animation , mipmap , drawables , images , assets ..
This methods takes as parameters :
- The res : this is an instance of the Resource class . The Resource class is used to access the resources of our application . it has some methods which allow us to get resources such as the color , the drawable .. using the resource Id
- The resource id , is the id of the bitmap that we want to access
- The options : that are used to decode our image .

Bitmap.decodeStream(InputStream is, Rect outPadding,Options opts)
We can use this method if we want to decode an input stream into a Bitmap . An input stream is an abstraction which allow us to get access to a file or to the web or to any other resource .