Quiero imprimir un mapa de bits a un teléfono móvil Bluetooth de la Impresora (Bixolon SPP-R200) – el SDK no ofrece direkt métodos para imprimir una imagen en memoria. Así que pensé acerca de cómo convertir un mapa de bits como este:

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

A un mapa de bits Monocromo. Yo soy de dibujo de texto negro sobre anteriores mapa de bits a través de un Lienzo, que funciona bien. Sin embargo, cuando tengo que convertir el anterior mapa de bits a un ByteArray, la impresora parece ser incapaz de manejar esos bytes. Sospecho que necesito una Matriz con un Bit por Píxel (Pixel sería blanco = 1 negro = 0).

Como no parece conveniente, fuera de la caja para hacer eso, una idea que yo tenía era de uso:

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

para Obtener los píxeles. Supongo, me tendría que usar de la siguiente manera:

int width = bitmap.getWidth();
int height = bitmap.getHeight();

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

Sin embargo – no estoy seguro acerca de un par de cosas:

  • En getPixels – ¿tiene sentido para, simplemente, pasar el ancho como el «Paso» argumento?
  • Supongo que tendría que evaluar la información de color de cada píxel y cambiar a negro o blanco (Y me gustaría escribir este valor en un nuevo objetivo de la matriz de bytes que que en última instancia, pasar a la impresora)?
  • Cómo evaluar de la mejor forma cada pixel de la información con el fin de decidir que debe ser de color negro o blanco? (La representación de mapa de bits es de color negro dolor sobre un fondo blanco)

¿Este enfoque se entiende? Hay una manera más fácil? No es suficiente simplemente hacer el mapa de bits negro & blanco, la cuestión principal es reducir la información de color de cada píxel en un bit.

ACTUALIZACIÓN

Según lo sugerido por Rubén primera vez que voy a convertir la imagen a un mapa de bits monocromo. y, a continuación, voy a repetir cada píxel:

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

Ahora Rubén sugirió a «leer el byte más bajo de cada uno de 32-bit pixel» – que se refieren a mi pregunta acerca de cómo evaluar el color del píxel. Mi última pregunta en este sentido: ¿puedo obtener el byte más bajo de simplemente hacer esto:

//Using the pixel from bitmap.getPixel(x,y)
int lowestByte = pixel & 0xff;
  • Tengo este QA protagonizó porque yo estaba trabajando en un concepto similar con respecto a la programación de la manipulación de matrices para convertirse en mapas de bits monocromos. Tengo una pregunta & su eventual respuesta aquí: stackoverflow.com/questions/17918978/… Si esto ayuda a la gente, por favor envíeme un correo electrónico y voy a venir para arriba con una respuesta adecuada a esta pregunta.
  • ¿Por qué usas GetPixels la carga de todos los píxeles en una única matriz… Entonces anidada recorrer el mapa de bits de NUEVO llamando individuales GetPixel llamadas (la menos eficiente posible)? Sólo el bucle a través de su matriz original, a continuación, utilizar SetPixels para empujar a toda la matriz de vuelta en el mapa de bits.
  • buen punto: el código es muy viejo xD – no creo que lo estamos utilizando en este formulario ya, pero como usted ha señalado correctamente, es muy ineficiente el modo en que está escrito allí. Siéntase libre de modificarlo de acuerdo a su sugerencia.
InformationsquelleAutor AgentKnopf | 2012-02-21

4 Comentarios

  1. 26

    Usted puede convertir la imagen a blanco y negro 32bpp el uso de un ColorMatrix.

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

    Que simplifica el color->monocromo de conversión. Ahora usted puede hacer un getPixels() y leer el byte más bajo de cada uno de los 32 bits del pixel. Si es <128 es un 0, de lo contrario es un 1.

    • Muchas gracias por tu respuesta! Sólo para aclarar el píxel de evaluación que he actualizado mi pregunta (por debajo de ACTUALIZACIÓN) esencialmente: ¿puedo obtener el byte más bajo de 32-bit int haciendo esto: int lowestByte = pixel & 0xff; ?
    • Sí. En realidad, el bit 7 del byte más bajo es exactamente el bit que usted desea para su 1bpp píxel. La expresión ‘(pixel & 0x80) >> 7’ le dará un ‘0’ o ‘1’ para que.
    • En una nota adicional: Puede ser, que la matriz de bytes lo que producen no es legible por android? El Uso De BitmapFactory.decodeByteArray(imageInBytes, 0, imageInBytes.de longitud) devuelve no utilizables de mapa de bits (para mostrar en android), y la impresora no le gusta ni…
    • Bueno en primer lugar, Android no admite 1bpp mapas de bits, y en segundo lugar BitmapFactory.decodificar* existe para decodificar PNG & JPEG. Usted deberá consultar la documentación de la impresora y exactamente lo que hace de soporte.
    • Gracias por la aclaración – jepp las impresoras SDk es un poco desordenado 🙁 se puede imprimir imágenes desde la web & sistema de archivos, pero no se puede imprimir en las imágenes de la memoria, por eso pensé en el envío de los bits directamente… voy a seguir intentando 🙂
    • Si se puede «imprimir imágenes desde la web», entonces puede ser que el controlador se ha incorporado en el soporte para formatos de imagen como PNG y/o JPEG. Trate de usar de mapa de bits.compress() con un ByteArrayOutputStream, obtener el comprimido bytes con toByteArray() y ver si se imprime.
    • Gracias por la sugerencia! Yo estaba considerando la posibilidad de enviar las imágenes a través de un socket, sin embargo, el SDK de los estados, que no es compatible con 32 bits de la imagen profundidades por lo tanto tendría que reducir la escala de la imagen a una Imagen de 1 bit de profundidad. Estamos haciendo ya en el código de c# donde la enviamos bit a bit a través de un raw socket de flujo, pero realmente estoy tratando de evitar eso y prefiero usar el SDK …
    • Yo descompilar el SDK (utilizando JD Gui) y que de hecho tienen un método para la conversión de mapas de bits para la adecuada matrices de bytes 🙂 y estoy sorprendido de lo bien que se lee – recuerdo una vez, cuando descompilar el código que se veía como un gran lío … me voy a dar un tiro con este.
    • Creo que estoy tratando de hacer lo mismo aquí. Hay una manera correcta de convertir el resultado int[] en un byte[] para un 1bpp de mapa de bits? Sólo puedo pensar en cambio de 1s y 0s en bytes como yo iterar a través de la int[]. No han descubierto nada.
    • ¿Intenta el enfoque u mencionado? Si sí lo hizo trabajar? Si no hágamelo saber y voy a tratar de pensar en abt algo…
    • así que después de la conversión a blanco y negro de imágenes de tamaño reducido ? (tamaño en kb)

  2. 10

    Bueno, yo creo que es muy tarde para responder a este hilo, pero yo también estaba trabajando en estas cosas a veces y decidí construir mi propia biblioteca que se va a convertir cualquier formato jpg o png imagen de 1bpp .bmp. La mayoría de las impresoras que requieren de 1bpp imágenes de apoyo de esta imagen (probado en una de esas :)).
    Aquí usted puede encontrar la biblioteca así como un proyecto de prueba que se utiliza para hacer un monocromo de un solo canal de la imagen. Siéntase libre de cambiar..:)

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

    Disfrutar..!! 🙂

    • Gracias por el esfuerzo! Estoy seguro de que va a ser útil a los demás y me voy a echar un vistazo al proyecto publicado así 🙂 .
  3. 5

    La conversión a blanco y negro con el mismo tamaño que la imagen original es no es suficiente para imprimir.

    Impresoras pueden imprimir solamente cada «pixel» (punto) como en blanco y negro porque cada mancha de tinta tiene sólo 1 color, por lo que debe utilizar mucho más los puntos que suficiente y ajustar su tamaño, densidad… para emular la escala de grises-como la sensación. Esta técnica se llama los semitonos. Se puede ver que las impresoras a menudo tienen una resolución de al menos 600 ppp, normalmente 1200-4800dpi, mientras que la pantalla de visualización de frecuencia por encima de 200-300 ppp.

    Android: Convertir un mapa de bits Monocromo de mapa de bits (1 Bit por Píxel)

    Por lo que su mapa de bits monocromo debe ser al menos 3 veces la resolución original en cada lado.

    • Te refieres tramado por casualidad? Yo había tramado ya integrado en mi código 🙂
    • No. El tramado es un comletely de negocio diferente. En 8-bits o más de mapa de bits en escala de grises que hay 255 (o más, dependiendo del número de bits que uso) de los niveles de gris, por lo que la resolución original está muy bien. Pero si el uso de mapa de bits monocromo, a continuación, casi todos los datos se perderán de manera significativa porque eres una reducción de más de 16,7 millones de colores a sólo 2. Semitonos aumenta la resolución y utiliza píxeles extra para dar el efecto de escala de grises como una manera de pasar esta limitación. Puede hacer referencia al enlace que me dio anteriormente.
    • Ah, gracias por aclarar 🙂 ! En mi particular caso de uso ya me dibujar en un lienzo en Negro & blanco. Sin embargo, también puede suceder que nos de la impresión de fotografías, por lo que para estos casos la mitad de tonificación realmente podría venir en práctico – gracias de nuevo 🙂 !
  4. 5

    Debe convertir cada pixel en el espacio HSV y utilizar el valor para determinar si el Píxel en la imagen de destino debe ser de color negro o blanco:

      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;

Dejar respuesta

Please enter your comment!
Please enter your name here