There are still cases where the barcode could not be rendered
because the process runs out of its memory limit. To avoid
a crash, catch the failure and log it. The barcode will
not be displayed, but at least the app will not crash.
For some reason when 1D barcodes are rendered in a smaller width,
they end up scrunched up and not using all available space.
As a result, they do not scale to the entire width of the screen.
In many cases the barcode is not scannable even in landscape.
To resolve this, render the 1D barcodes in a larger space. The space
is still bounded, to prevent OOMs on tablets or really
wide screen devices.
When reducing the pixel size of the width, if the height is not
scaled to match then 1D barcodes end up being squished and are
too narrow to scan. To avoid this, scale the height to match.
Then, when the barcode is loaded into a Bitmap it will scale up
to the correct size.
It was found that on a Galaxy S4 a barcode width of 400 px started
to see some blurriness, but 500 px still looked sharp. Reducing
the maximum width to 500 px.
To reduce the amount of memory used in generating barcodes, limit
the width of the barcodes to no more than 3x the height.
This should be plenty sufficient to generate a usable barcode.
On devices with a really long width generating a barcode of 200x2560
is not useful and can result in an OutOfMemoryError.
It was observed that some barcode encoders will fail if the
data passed to them is not valid for the format. For example,
the ITF encoder will throw an ArrayIndexOutOfBoundsException
on the input "this is a test".
It turns out that the library used to create datamatrix barcodes
returns the smallest image necessary to contain the barcode. That
is, the size passed into the barcode writer. If the ImageView
scales the tiny image itself into the full size it will use
bi-linear filtering, which results in a blurry barcode.
To avoid this, if scaling is needed do so without using filtering.
This change moves the generation of the barcode into its
own async task. In addition, the size of the ImageView is
used to determine the barcode size to use.
There will be cases when the size of the ImageView will not
be known when the barcode generation starts. This will be resolved
in a future commit.