Android:将位图转换为单色位图(每像素1位)

我想打印一个位图到移动蓝牙打印机(Bixolon SPP-R200) – SDK不提供打印内存映像的direkt方法。 所以我想这样转换一个位图:

Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 

单色位图。 我正在使用Canvas在给定的位图上绘制黑色文本,效果很好。 但是,当我将上述位图转换为一个ByteArray,打印机似乎无法处理这些字节。 我怀疑我需要一个每像素一位数组(像素将是白色= 1或黑色= 0)。

由于似乎没有任何方便的方法,所以我有一个想法是使用:

 bitmap.getPixels(pixels, offset, stride, x, y, width, height) 

获取像素。 我假设,我不得不使用它如下:

 int width = bitmap.getWidth(); int height = bitmap.getHeight(); int [] pixels = new int [width * height]; bitmap.getPixels(pixels, 0, width, 0, 0, width, height); 

但是 – 我不确定几件事情:

  • 在getPixels中 – 简单地将宽度作为“Stride”parameter passing是否有意义?
  • 我想我将不得不评估每个像素的颜色信息,并将其切换为黑色或白色(我将这个值写入一个新的目标字节数组,我将最终传递给打印机)?
  • 如何最好地评估每个像素的颜色信息,以决定它应该是黑色还是白色? (呈现的位图是在白色背景上的黑色痛苦)

这种方法是否有意义? 有更容易的方法吗? 仅将位图变成黑白是不够的,主要的问题是将每个像素的颜色信息减less到一位。

UPDATE

正如Reuben所build议的那样,我将首先将位图转换为单色位图。 然后我将遍历每个像素:

  int width = bitmap.getWidth(); int height = bitmap.getHeight(); int[] pixels = new int[width * height]; bitmap.getPixels(pixels, 0, width, 0, 0, width, height); // Iterate over height for (int y = 0; y < height; y++) { int offset = y * height; // Iterate over width for (int x = 0; x < width; x++) { int pixel = bitmap.getPixel(x, y); } } 

现在Reubenbuild议“读取每个32位像素的最低字节” – 这与我如何评估像素颜色有关。 我在这方面的最后一个问题:只要做到这一点,我得到最低的字节:

 // Using the pixel from bitmap.getPixel(x,y) int lowestByte = pixel & 0xff; 

Solutions Collecting From Web of "Android:将位图转换为单色位图(每像素1位)"

您可以使用ColorMatrix将图像转换为单色32bpp。

 Bitmap bmpMonochrome = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bmpMonochrome); ColorMatrix ma = new ColorMatrix(); ma.setSaturation(0); Paint paint = new Paint(); paint.setColorFilter(new ColorMatrixColorFilter(ma)); canvas.drawBitmap(bmpSrc, 0, 0, paint); 

这简化了颜色 – >单色转换。 现在你可以做一个getPixels()并读取每个32位像素的最低字节。 如果它<128,则为0,否则为1。

那么我认为它现在已经很晚了回复此线程,但我也有时回来这个东西,并决定build立我自己的图书馆,将任何JPG或PNG图像转换为1bpp .bmp。 大多数需要1bpp图像的打印机都会支持这个图像(在其中一个:)上进行testing)。 在这里您可以find图书馆以及使用它制作单色单通道图像的testing项目。 随意改变它.. 🙂

https://github.com/acdevs/1bpp-monochrome-android

请享用..!! 🙂

与原始位图完全相同的大小转换为单色不足以进行打印。

打印机只能将每个“像素”(点)打印为单色,因为每个墨点只有一种颜色,所以它们必须使用的点数要多得多,并调整它们的大小,密度以模拟灰度级的感觉。 这种技术被称为半色调 。 您可以看到打印机的分辨率通常至less为600dpi,通常为1200-4800dpi,而显示屏幕常常在200-300ppi之间。

半色调

所以你的单色位图应该至less是每一边原始分辨率的3倍

您应该将每个像素转换为HSV空间,并使用该值来确定目标图像上的像素是黑色还是白色:

  Bitmap bwBitmap = Bitmap.createBitmap( bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.RGB_565 ); float[] hsv = new float[ 3 ]; for( int col = 0; col < bitmap.getWidth(); col++ ) { for( int row = 0; row < bitmap.getHeight(); row++ ) { Color.colorToHSV( bitmap.getPixel( col, row ), hsv ); if( hsv[ 2 ] > 0.5f ) { bwBitmap.setPixel( col, row, 0xffffffff ); } else { bwBitmap.setPixel( col, row, 0xff000000 ); } } } return bwBitmap;