Spanish Imprimir logo/imagen en impresora bluetooth

vecino

Well-Known Member
Licensed User
Longtime User
Hola, amigos, por aquí de nuevo dando la lata, espero que todos estén bien.
Hace un par de años, precisamente un 28 de abril como hoy pero de 2021, inicié un hilo para solucionar una serie de problemas que tenía con la impresión por bluetooth.
Gracias a los que participaron logré solucionarlo y quedó funcionando perfectamente, nadie se ha quejado y espero que siga asi.
Pero, siempre hay un pero, un cliente me ha pedido que imprima al principio del ticket el logo de la empresa, y yo voy y... no lo consigo.
Llevo varios días con esto porque quería solucionarlo yo solito, pero nada, me rindo, voy a pediros ayuda. Os voy a poner el código que estoy usando para conectar por BT y para imprimir una vez ha conectado, ya digo, funciona bien, y lo que necesito es añadir ahí que imprima también un logo/imagen.
Muchas gracias.

B4X:
Globals
    Dim BTconexSerial As Serial
    Dim BTadmin As BluetoothAdmin
    Dim OutStream As OutputStream

    Dim twOut As TextWriter
    Dim cPrinterBTmac As String = "DC:0D:30:DA:75:12"

B4X:
Sub btPrint_Click As ResumableSub
    If Not (BTadmin.IsInitialized) Then
        Wait For (ConectarBT) complete (bRes As Boolean)
        If Not(bRes) Then
            ToastMessageShow("No se pudo conectar a BT",False)
            Return False
        End If
    End If

    If Not(globales.BTadmin.IsEnabled) Then
        BTadmin.Enable
        Wait For BTadmin_StateChanged (NewState As Int, OldState As Int)
        If NewState = BTadmin.STATE_OFF Or NewState = BTadmin.STATE_TURNING_OFF Then
            ToastMessageShow("No se pudo habilitar BT",False)
            Return False
        End If
    End If
      
    If Not (BTconexSerial.IsInitialized) Then
        If Not(BTconexSerial.IsEnabled) Then
            BTconexSerial.Initialize("BTconexSerial")
        End If
    End If
    BTconexSerial.Connect( cPrinterBTmac )
    Wait For BTconexSerial_Connected(Success As Boolean)
    If Success Then
      
        OutStream = BTconexSerial.OutputStream
        twOut.Initialize2(OutStream,"windows-1252")
        '
        ' <--- Aqui debería imprimir el logo/imagen !!!!!
        '
        '
        twOut.Write( "Ticket 123" )  ' <--- Aquí va el texto de la venta
        twOut.Flush
        '
        twOut.Close
        OutStream.Close
        BTconexSerial.Disconnect
    End If
    '
    Return True
End Sub

B4X:
Sub ConectarBT As ResumableSub
    Dim bOk As Boolean = False
    '
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result = False Then
        ToastMessageShow("Sin permisos", False)
        Return bOk
    End If
    '
    If cPrinterBTmac.Trim.Length=0 Then
        ToastMessageShow("Elija printer BT en Menú Utilidades",False)
    Else
        ProgressDialogShow("Conectando BT...")
        Try
            BTadmin.Initialize("BTadmin")
            If Not (BTadmin.IsEnabled) Then
                BTadmin.Enable
                Wait For BTadmin_StateChanged (NewState As Int, OldState As Int)
                If NewState = BTadmin.STATE_OFF Or NewState = BTadmin.STATE_TURNING_OFF Then
                    ToastMessageShow("No se pudo habilitar BT",False)
                Else
                    ToastMessageShow("Bluetooth activado",False)
                    bOk = True
                End If
            Else
                bOk = BTadmin.IsEnabled
            End If
            '
        Catch
            ToastMessageShow("No se pudo habilitar bluetooth",False)
            bOk = False
        End Try
        ProgressDialogHide
    End If
    '
    Return bOk
End Sub
 
Last edited:

vecino

Well-Known Member
Licensed User
Longtime User
Se me olvidó comentar que la impresora la selecciono desde otra opción de la aplicación, y no hay problema con ello tampoco, solamente es imprimir el dichoso logo de la empresa.
 

josejad

Expert
Licensed User
Longtime User
Hola vecino:

Ni idea de imprimir ni de cómo usar impresoras. Imagino que habrás estado mirando por el foro, por lo que he podido leer, no hay una solución por aquí funcionando.
La respuesta quizás más completa que he podido encontrar, es este hilo, en el que alguien dice que la forma más sencilla de hacerlo es descargando la imagen en la impresora de forma que se quede grabada en su eepron, y mediante un comando decirle que imprima ese gráfico.
Ya el resto de cosas que la gente pregunta (imprimir la imagen junto al texto, imprimir distintas imágenes... ) no parece haber una solución por aquí.

Aquí hay una clase de agraham (que es un máquina), que al parecer imprime imágenes, no sé si lo has visto
 

vecino

Well-Known Member
Licensed User
Longtime User
Hola, Jose, hay muchas opciones pero ninguna me han servido para implementarla junto a mi código. Mejor dicho, yo no he sabido implementarlo.
La clase de agraham sí que la he probado, pero le hace falta unos cuantos ajustes en cuestión de permisos, pues no los controla, está obsoleta, y además a veces no he conseguido que conecte, y otras veces que sí ha conectado al intentar imprimir no hace nada.
También es verdad que algunas veces conecta e imprime a la primera, sobre todo si se acaba de reiniciar el dispositivo.
Pero el problema es que yo no puedo decirles a los clientes que prueben una y otra vez, y que reinicien cada vez que no les imprima.
Por eso quiero adaptar la impresión de imágenes a mi código, porque funciona perfectamente desde hace 2 años justo hoy, y ni uno de los clientes me ha llamado nunca por problemas de conexión/impresión.
 

vecino

Well-Known Member
Licensed User
Longtime User
Y lo de cargar la imagen en la impresora solamente sirve para algunas impresoras que tienen esa característica, pero no es nada normal en las impresoras "normales", y menos todavía en las que estoy usando, impresoras de estas móviles, que son las que llevan mis clientes en sus camiones/furgonetas de reparto.

fnkHlvW.png
 

josejad

Expert
Licensed User
Longtime User
Son todas de la misma marca? Has visto si tienen algún tipo de manual que indique algo sobre la impresión de imágenes?
 

vecino

Well-Known Member
Licensed User
Longtime User
Los clientes compran las que les parece, las más baratas que encuentran. Las que he probado no tienen esa posibilidad de almacenar imágenes para imprimir, eso lo he visto en impresoras "de marca", que suelen ser caras.
 

vecino

Well-Known Member
Licensed User
Longtime User
Llevo varios días haciendo pruebas sin parar, probando todo tipo de código que he encontrado por los foros, y hay algo que consigue imprimir algunas veces, pero es muy inestable, a veces salen errores de memoria, otras no imprime nada, y varias veces ha mostrado la imagen.
Lo he conseguido intercalando este código en el mío, justo al final de terminar de imprimir el ticket:
B4X:
                    Dim GS As String = Chr(29)
                    twOut.Write(GS & "v0")
                    twOut.Flush
                    twOut.close
                    
                    Dim aimg As AnImage
                    aimg.Initialize
                    aimg.Data = File.ReadBytes(File.DirAssets, "test-firma.jpg")
                    aimg.Height=66
                    aimg.Width=120
                    Dim xh As Int = aimg.width / 256
                    Dim xl As Int = aimg.width - xh * 256
                    Dim yh As Int = aimg.height / 256
                    Dim yl As Int = aimg.height - yh * 256
                    Dim params(5) As Byte
                    params(0) = 0 
                    params(1) = xl
                    params(2) = xh
                    params(3) = yl
                    params(4) = yh
                    OutStream.WriteBytes(params,0,params.Length-1)
                    OutStream.WriteBytes(aimg.data,0,aimg.Data.Length-1)
                    OutStream.Flush
 

vecino

Well-Known Member
Licensed User
Longtime User
Creo que voy a usar la clase de agraham, voy a intentar adaptarla a mi programa, ¡¡¡miedo me da!!! ?porque siempre surgen imprevistos y estos clientes son comerciales y repartidores que no les puede fallar la impresión.
 

omo

Active Member
Licensed User
Longtime User
I think I'm going to use agraham's class, I'm going to try to adapt it to my program, it scares me!!! ?because unforeseen events always arise and these clients are commercial and delivery people who cannot fail to print

Sorry, I don't speak Spanish, I only translated to English to read your question. You can translate back to read this comment. Have you tried decoding and encoding logo image to base64 string maybe it will be easy to print the logo image? You can check @
 

vecino

Well-Known Member
Licensed User
Longtime User
Hello omo, thank you for your help.
I can encode it in base64, but can it be sent to the printer in that way?
In other words, do printers decode base64 to print an image?
Thank you.
 

omo

Active Member
Licensed User
Longtime User
I think it should be possible, but I have not tried it personally with Bluetooth printer, but I have used it in order related areas or you can convert to base64, then use Erel class to print to PDF with image, then send for printing via Bluetooth. Check these additional links too:

https://stackoverflow.com/questions...and-print-that-image-in-a-bluetooth-printer-i

 

vecino

Well-Known Member
Licensed User
Longtime User
I've been trying, but it's been impossible, I'm not that skilled.
 

Dadaista

Active Member
Licensed User
Longtime User
Hola Yo utilizo una clase que vi por aqui hace tiempo y la he ido manipulando y adecuandola a mis necesidades. La tengo cargada en una app de windows y funciona sin problemas pero lo que te digo... es en b4j y me da igual si la impresora es BT o es usb o red. Pero lo que te comento... esto lo utilizo en B4j bajo Windows con la libreria jFX8Print

En mi caso el usuario elige el archivo de imagen que quiere yo la salvo para luego imprimirla en el ticket

Esta es la funcion que "lo hace". Te la pego "tal cual"... te sobraran unas cuantas cosas... mira a ver si la puedes "colocar" entre tu codigo y te soluciona algo

B4X:
Sub getBytesForBitmap(bitmapName As String, Temporal As Boolean) As Byte() ', centered As Boolean ) As Byte()
    Dim dibujo As Image, x As Int
    Dim out As OutputStream
    
    If Temporal Then
        dibujo.initialize (File.DirTemp, bitmapName)
    Else
        dibujo.initialize (Main.xui.DefaultFolder & "/Config", bitmapName)
    End If
    
    out.InitializeToBytesArray(0)                        ' define start size (0)
    'out.WriteBytes(Array As Byte(0x1B,0x40),0,2)         ' ESC @         Initialize printer
'    If centered Then
'        out.WriteBytes(Array As Byte(0x1B,0x61,1),0,3)  ' ESC a  '1'    Center justification
'    End If
    
    out.WriteBytes(Array As Byte(0x1D,0x76,0x30,0x30),0,4)        ' ESC * 33    Bit image mode, 24-dot double density (es el 33) --> 200dpi
    Dim mbytes As Int = (dibujo.Width + 7)/8
    Dim wl As Int = Bit.And(mbytes,0xFF)
    Dim wh As Int = Bit.ShiftRight(mbytes,8)
    Dim hl As Int = Bit.And(dibujo.height,0xFF)
    Dim hh As Int = Bit.ShiftRight(dibujo.height,8)

    out.WriteBytes(Array As Byte(wl,wh,hl,hh),0,4)    ' Width_low, Width_high
    
    For y = 0 To dibujo.Height-1
        For x = 0 To dibujo.Width-1 Step 8
            Dim slice As Byte = 0
            For b = 0 To 7
                If x+b < dibujo.Width Then
                    If Bit.And(dibujo.GetPixel(x+b,y), 0xFFFFFF) <> 0xFFFFFF Then
                        slice = Bit.Or(slice, Bit.ShiftRight(0x80, b))
                    End If
                End If
            Next
            out.WriteBytes(Array As Byte(slice),0,1)
        Next
    Next

    Return out.ToBytesArray()
End Sub

Dentro de la clase hay esto
B4X:
Public gh As B4XBytesBuilder

y esto
B4X:
Public Sub PrintMyLogo
    'EL ARCHIVO VIENE YA CENTRADO PORQUE LO CENTRO PREVIAMENTE
    gh.Append(getBytesForBitmap("tktmilogo.cfg", False))', True))
End Sub

Aunque veas que el archivo tiene extension .cfg es un archivo de imagen. Lo salvo con esa extension a proposito.

Desde fuera de la clase en el principal...

B4X:
dim impresora as printing
impresora.Initialize(sImpresoraDefecto)
impresora.Clear
impresora.Center
impresora.PrintMyLogo

La impresora que utilizo es de 80. La tuya es mas pequeña

Espero que te sirva de ayuda o al menos que te de un punto de partida para que puedas imprimir los logos

Salu2
 

vecino

Well-Known Member
Licensed User
Longtime User
Seguro que funciona, aunque lo he probado y crea la imagen, la envía a la impresora... pero no hace nada :/
La verdad es que siempre he sido muy torpe para manejar las impresoras.
De todas formas voy a tener que dejarlo hasta el martes porque me he quedado sin papel de tantas pruebas :eek:
He estado reimprimiendo encima una y otra vez en el único rollo que tenía y ya es imposible saber si está imprimiendo bien o no.
papelimpresora.jpeg
 

aviario

Active Member
Licensed User
Longtime User
con esta clase de agraham imprimo los logos sin problema

Sub sBImprime_Logo

Printer1.Reset
Dim bmp As Bitmap
' Load an image to print and resize it to the maximum mage dimensions for the printer
bmp.InitializeResize(File.DirAssets, "gochu.jpg", 576, 512, True) 'ignore

' Convert the RGB image to one with luminance values
Dim myimage As AnImage = Printer1.ImageToBWIMage(bmp)

' Choose thresholding the image or dithering it to get a black and white bit image
myimage = Printer1.DitherImage2D(myimage, 128)

' Send the black and white bit image to the printer
myimage= Printer1.PackImage(myimage)
Printer1.WriteString(CRLF) ' nudge the printer to show the user something is happening
Printer1.PrintImage(myimage)



End Sub
 

vecino

Well-Known Member
Licensed User
Longtime User
Hola, unas dudas, aviario, lo de "576,512" ¿hay que poner siempre esa medida o hay que poner la medida de la imagen a imprimir?
Esa línea la terminas con el comentario 'ignore ¿qué hay que ignorar?
Otra duda: ¿Siempre hay que dar esos pasos? o sea: ¿imagetobwimage, ditherimage2d y packimage... antes de printimage?
Saludos.
 

vecino

Well-Known Member
Licensed User
Longtime User
Y aparte de eso, estoy intentando implementar la clase de agraham a mi programa y me surgen unas cuantas dudas que no sé cómo la solucionais.
Por ejemplo, esa clase no implementa "async", no hay "wait for", así que cuando se ejecuta (por ejemplo) printer1.connect ocurre que el programa sigue su curso cuando todavía no se ha conectado, e incluso puede que ni se conecte porque la impresora está apagada, o está encendida pero no está activo bluetooth en el dispositivo, etc.
Entonces mi duda es esa, ¿cómo teneís resuelto todo ese asunto?
Gracias.
 

josejad

Expert
Licensed User
Longtime User
Hola vecino:

Sin tener mucha idea ahora mismo de esto, te digo algunas ideas a ver qué tal:

Hola, unas dudas, aviario, lo de "576,512" ¿hay que poner siempre esa medida o hay que poner la medida de la imagen a imprimir?
Según el comentario de la clase de agrahan esto dimensiona la imagen al tamaño de imagen máximo de la impresora. Por lo que entiendo que depende de la impresora, echa un ojo a ver qué tamaño máximo puede imprimir la tuya, prueba con esas para empezar.

Esa línea la terminas con el comentario 'ignore ¿qué hay que ignorar?
Eso es un mensaje para el ide, para que el compilador no te lance un warning. Si lo quitas, verás que aparece el error: "el siguiente valor no utiliza unidades de pantalla...", que se puede omitir, de ahí el 'ignore

¿imagetobwimage, ditherimage2d y packimage... antes de printimage?
Son "efectos" a aplicar a la imagen para que salgan mejor en la impresora. Entiendo que si tienes el logo en blanco y negro o a un solo color, no te hará falta aplicarlos.

no hay "wait for", así que cuando se ejecuta (por ejemplo) printer1.connect ocurre que el programa sigue su curso cuando todavía no se ha conectado
Hay un evento Serial1_Connected, por lo que puedes hacer algo como (no lo he probado) (código tomado de este hilo)

B4X:
Dim sf As Object = Printer1.Initialize(Me, "Printer1")
Wait For (sf) Printer1_Connected (Success As Boolean)
If Success Then
   Log("Impresora conectada")
Else
   Log("Error conectando")
End If
 
Last edited:

aviario

Active Member
Licensed User
Longtime User
Esas son las medidas que quieres que te imprima el logo

Sobre lo segundo yo lo que hago es comprobar si la impresora esta conectada

If Printer1.IsBluetoothOn = False Then
Msgbox("Habilite Bluetooth y conecte una impresora Bluetooth.", "")
Else If Printer1.IsConnected = False Then
Printer1.Connect
End If

y automáticamente entra en esta sub

Sub Printer1_Connected (Success As Boolean)

If Success Then
Imprime_Visita
Tp.Sleep(1000)
Printer1.Disconnect
Else
Msgbox("", "Error Conectando Impresora")
End If

End Sub
 
Top