Android Question (Solved) How to convert image to bitmap? (In-Line Java code)

LGS

Member
Licensed User
Longtime User
Hello everyone.
I am using itextpdf to create a pdf, and everything works fine.
In addition to this I need to convert the image to bitmap, so that it is returned in the function.

B4X:
public void draw128(String filename,String ruta) throws IOException, DocumentException {
        
        String configFilePath = ruta;
        Document document = new Document(new Rectangle(340, 842));
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(configFilePath + filename));
        document.open();
        PdfContentByte cb = writer.getDirectContent();
          
        Barcode128 uccEan128 = new Barcode128();
        uccEan128.setCodeType(Barcode.CODE128_UCC);
        uccEan128.setCode("(01)00000090311314(10)ABC123(15)060916");

        Image imagetoConvert = uccEan128.createImageWithBarcode(cb, BaseColor.BLACK,BaseColor.BLACK);

        document.add(imagetoConvert);
        document.close(); 'The pdf file is successfully created
          
          // HOW CONVERT imagetoConvert to Bitmap?
          // Bitmap bitmaptoReturn = ???????
          // return bitmaptoReturn;         
}

I appreciate all the support
 

Attachments

  • CB.zip
    10.9 KB · Views: 104

drgottjr

Expert
Licensed User
Longtime User
the Image is not an android image. it belongs to
itextpdf. there are routines to convert android.media.Image
to bitmap, but not itextpdf.text.Image to bitmap.

2 suggestions:
you can extract an image from a pdf. search the forum.

itextpdf.text.Image does offer a getRawData() method
which returns a byte array. with that in hand, there may
be a number of possibilities for you. you'll have to look
into exactly what an Image is. the byte array returned from
getRawData() may not be in some form recognizable to
android. if it is, you can easily return the byte[] to b4a
and convert to bitmap.

i could be wrong about the availability of an itextpdf.text.Image to bitmap conversion routine somewhere; i thought it was important to mention that itextpdf's Image class is not the same as the android.media.Image class.
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
I take a pic with my android device and then later add it to a PDF making use of itext and it works fine. Are you trying to do something similar? Have not looked at your project in the post above but can maybe assist with some code if that is what you are trying to accomplish
 
Upvote 0

LGS

Member
Licensed User
Longtime User
Hello Mr Schoeman. Thanks for your time.
I am using itextpdf to create an image (Barcode) and this is added to the .pdf. Everything works well.
But, in addition to this, I need to create the same image (Barcode) in .png format.
I am looking for a way to return a bitmap to B4A in order to create the .png.
But if there is any way to create the .png in the function (In-Line Java code) that would be great.

I really appreciate your support
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
This converts from a Android Bitmap to an iText Image


B4X:
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.ByteArrayOutputStream;

import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.Image;

....
.....
.....
.....

                ByteArrayOutputStream stream=new ByteArrayOutputStream();
                linebitmap.compress(Bitmap.CompressFormat.PNG,100,stream);
                Image thisImage = Image.getInstance(stream.toByteArray());               
               
                cell = new PdfPCell();
                cell.setColspan(1);
                cell.addElement(thisImage);
                table.addCell(cell);

So, I guess there should be a way to reverse this process....
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
Use something that is more Android friendly to create the code128 barcode bitmap with (such as ZXing - there are samples on the forum). Then you can do with the bitmap in Android whatever you want (save to png, bmp, etc). Then pass the Android bitmap to the itext inline java code to convert the Android bitmap to an iText image so that you can add the iText image to your PDF.

I can try to make you a sample code if you dont follow the above

 
Last edited:
Upvote 0

LGS

Member
Licensed User
Longtime User
Mr drgottjr
I tried your suggestion to return getRawData() to B4A , but it is returning Null.
I'm not sure if the way I'm doing it is the right. I attach the project.
B4X:
Private Sub Button1_Click
    Dim bmp() As Byte = itl.draw128
    If bmp = Null Then
        Log("NULL")
    Else
        Log("Data")
    End If
End Sub

Public Sub draw128() As Byte()
    Dim archivo As String = "Codigo.pdf"
    Return nativeMe.RunMethod("draw128", Array(archivo,Main.CarpetaRaiz&"/"))
End Sub

'In-Line Java Code
public byte[] draw128(String filename,String ruta) throws IOException, DocumentException {
        
          String configFilePath = ruta;
        Document document = new Document(new Rectangle(340, 842));
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(configFilePath + filename));
        document.open();
        PdfContentByte cb = writer.getDirectContent();
          
        Barcode128 uccEan128 = new Barcode128();
        uccEan128.setCodeType(Barcode.CODE128_UCC);
          uccEan128.setCode("(01)08456789567807(15)080423(10)89B23");

          Image imagetoConvert = uccEan128.createImageWithBarcode(cb, BaseColor.BLACK,BaseColor.BLACK);

        document.add(imagetoConvert);
          document.close();
          
          byte[] data = imagetoConvert.getRawData();
          return data;         
}

I haven't tried to extract the image from the .pdf yet

Mr Schoeman
I am trying to use itextpdf because I am creating GS1-128 (EAN/UCC-128) codes. This code is a special form of code 128. It provides for the use of a special sign (the FNC1) immediately after the start sign. This direct sequence of start signs and FNC1 at the beginning is a unique indicator for a GS1-128. And it allows to create (AI) Application Identifiers. Attached example image.
I tried to create it with ZXING core library using drawCode128, but it doesn't render properly. I have used ZXING core library to create other types of code. If I could use it to create this kind of code that would be great.

Thanks again for the support.
 

Attachments

  • CB 2.zip
    11.1 KB · Views: 80
  • Code.PNG
    Code.PNG
    14.4 KB · Views: 82
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
the b4a routines look like they should work.

assuming your inline code is correct (that is to say, uccEan128.createImageWithBarcode() returns a valid itextpdf.text.Image), you probably
should get something other than null for imagetoConvert.getRawData().

i read that getRawData() assumes the Image is of a particular type. look at line #853 in

there are a lot of interesting methods in that code. if i were using the api, i'd be testing
them to see exactly what i was dealing with when i call createImageWithBarcode(). you may be able to create an Image that is actually
useful to b4a.

getting the Image bytes is not working for me. i've tried getrawdata() and getoriginaldata() and several different ways to copy or force the Image to
some other manageable type. not happening. i've only been able to determine that its type is pdftemplate. in theory there seem to be a number of
ways to change the type to, eg jpeg, but i haven't had any luck yet. sorry.

side point: i can read the code with zxing and with google's new mlkit, but not with google's (now deprecated) mobile vision (which is zxing on steroids).
if anyone can get zxing to generate your 128 correctly on android, it would be @johanschoeman. so give him the data, and let him take a crack at it.
 

Attachments

  • 2.png
    2.png
    155 KB · Views: 95
  • 3.png
    3.png
    161.5 KB · Views: 107
  • 4.png
    4.png
    157.5 KB · Views: 93
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
You could convert the Image to a byte array (source: https://www.b4x.com/android/forum/t...byte-array-with-resize-quality-options.91746/), return that to B4A and then use B4A to convert the byte array to a Bitmap (source: https://www.b4x.com/android/forum/threads/b4x-bytes-to-file.70111/post-445167)

Java part
Java:
// required imports
import java.io.ByteArrayOutputStream;
import javax.imageio.ImageIO;

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(imageToConvert, "jpg", baos);
baos.flush();
byte[] imageBytes = baos.toByteArray();
baos.close();
return imageBytes;

Then use the following routine to convert the returned bytes to a Bitmap
B4X:
Public Sub BytesToImage(bytes() As Byte) As Bitmap
   Dim In As InputStream
   In.InitializeFromBytesArray(bytes, 0, bytes.Length)
   Dim bmp As Bitmap
   bmp.Initialize2(In)
   Return bmp
End Sub
 
Upvote 0

LGS

Member
Licensed User
Longtime User
You could convert the Image to a byte array (source: https://www.b4x.com/android/forum/t...byte-array-with-resize-quality-options.91746/), return that to B4A and then use B4A to convert the byte array to a Bitmap (source: https://www.b4x.com/android/forum/threads/b4x-bytes-to-file.70111/post-445167)

Java part
Java:
// required imports
import java.io.ByteArrayOutputStream;
import javax.imageio.ImageIO;

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(imageToConvert, "jpg", baos);
baos.flush();
byte[] imageBytes = baos.toByteArray();
baos.close();
return imageBytes;

Then use the following routine to convert the returned bytes to a Bitmap
B4X:
Public Sub BytesToImage(bytes() As Byte) As Bitmap
   Dim In As InputStream
   In.InitializeFromBytesArray(bytes, 0, bytes.Length)
   Dim bmp As Bitmap
   bmp.Initialize2(In)
   Return bmp
End Sub
Hello Mr OliverA.
Trying the submitted code, the following error is displayed:
src\b4a\example\itextlib.java:17: error: package javax.imageio does not exist
import javax.imageio.ImageIO;

Any idea about it
Thank you
 

Attachments

  • Error.PNG
    Error.PNG
    16.4 KB · Views: 81
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Apologies, the solution would only work in B4J, so please disregard.
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
A possible solution depending on how much effort you want to put into it:
1. The code below creates your code128 successfully - I have successfully added it to a PDF
2. The code returns a byte array (byte[]) with the width of each bar in the code128 barcode
3. When I log what is in the byte array I get:

B4X:
2
1
1
2
3
2
4
1
1
1
3
1
2
2
2
1
2
2
2
1
2
2
2
2
2
1
2
2
2
2
2
1
2
2
2
2
2
1
4
1
2
1
2
1
2
3
2
1
1
2
2
1
3
2
1
2
2
2
3
1
2
2
1
3
1
2
1
1
4
1
3
1
1
1
1
3
2
3
1
3
1
1
2
3
1
3
1
3
2
1
1
2
3
2
2
1
1
1
3
1
4
1
3
1
2
1
3
1
4
1
1
1
3
1
1
1
3
2
2
2
1
2
2
2
1
3
2
2
1
2
1
3
1
2
3
1
2
2
1
2
4
1
1
2
2
3
3
1
1
1
2
0
0
0
0
0
0


B4X:
        uccEan128.setCodeType(Barcode.CODE128_UCC);
        uccEan128.setCode("(01)00000090311314(10)ABC123(15)060916");

        document.add(uccEan128.createImageWithBarcode(cb, BaseColor.BLUE,
                BaseColor.BLACK));
               
        String bCode;
        if (uccEan128.getCodeType() == uccEan128.CODE128_RAW) {
            int idx = uccEan128.getCode().indexOf('\uffff');
            if (idx >= 0)
                bCode =  uccEan128.getCode().substring(0, idx);
            else
                bCode = uccEan128.getCode();
        }
        else {
            bCode = uccEan128.getRawText(uccEan128.getCode(), uccEan128.getCodeType() == uccEan128.CODE128_UCC);
        }
        int len = bCode.length();
        int fullWidth = (len + 2) * 11 + 2;
        byte bars[] = uccEan128.getBarsCode128Raw(bCode);
           
        document.close();
       
        return bars;

1654940943251.png



So, the byte array contains the width of each bar (black/white) relative to one another. You can use it to draw the code128 on a canvas and then save it to png / bmp / etc. You will have to draw the text on the canvas below the barcode. I have copied the code128 barcode image created by the inline java code into the attached zipped Excel workbook and have started filling columns with the values in the byte array and they seem to correspond 100% for as much as what I have done thus far. You can complete it if you feel like doing so to ensure it matches 100% (those values in RED inside the workbook has already been used to draw the barcode in the excel columns


1654941822242.png
 

Attachments

  • BARS.zip
    25.1 KB · Views: 68
Last edited:
  • Like
Reactions: LGS
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
I have used the values in the byte array to draw the barcode on a B4J canvas - same can be done with it on an Android canvas. This is what it draws and it scans 100%

1654945713928.png


B4X:
    Dim mybytes() As Byte
    mybytes = itl.createPdf(mystring)
    
    
    Dim barwidth As Double = 2dip
    Dim lft As Double = 10dip
    For i = 0 To mybytes.Length - 1
        If i Mod 2 = 0 Then
            Canvas1.DrawRect(lft, 10dip, barwidth * mybytes(i), 80dip, fx.Colors.Black, True, 0)
        Else
            Canvas1.DrawRect(lft, 10dip, barwidth * mybytes(i), 80dip, fx.Colors.White, True, 0)
        End If
        lft = lft + barwidth * mybytes(i)
    Next

"mybytes" is the byte array returned from the inline java code that holds the relative width of each bar/space
 
Upvote 0

LGS

Member
Licensed User
Longtime User
Mr Schoeman.
Really the values in the byte array are the key, this must be the solution.
I have already used canvas in B4A to draw other code.
The byte array was what was needed.
I'm not at home. But when I get back I'll try the suggested and report the results.

Thank you for your support... šŸ¤
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
B4J sample project attached - I am using iText-5.0.5.jar
Add the inline java code to your B4A project and use the returned byte array to draw the barcode on a B4A canvas. Sure you will figure it out!

Sample code (Main):

Main:
#Region  Project Attributes
    #MainFormWidth: 800
    #MainFormHeight: 600
    #AdditionalJar: iText-5.0.5

#End Region

Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
   
    Dim itl As itextlib
   
    Private Canvas1 As Canvas
    Private Label1 As Label
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.SetFormStyle("UNIFIED")
    MainForm.RootPane.LoadLayout("main") 'Load the layout file.
    MainForm.Show
'    MainForm.BackColor = fx.Colors.ARGB(100,0,0,255)
   
    itl.Initialize
   
    Dim mystring As String = "(01)00000090311314(10)ABC123(15)060916"
   
 
    Dim mybytes() As Byte
    mybytes = itl.createPdf(mystring)
    For i = 0 To mybytes.Length - 1
        Log(mybytes(i))
    Next
   
   
    Dim barwidth As Double = 2dip
    Dim lft As Double = 10dip
    For i = 0 To mybytes.Length - 1
        If i Mod 2 = 0 Then
            Canvas1.DrawRect(lft, 10dip, barwidth * mybytes(i), 80dip, fx.Colors.Black, True, 0)
        Else
            Canvas1.DrawRect(lft, 10dip, barwidth * mybytes(i), 80dip, fx.Colors.White, True, 0)
        End If
        lft = lft + barwidth * mybytes(i)
    Next  
   

    Label1.Text = ""
   

   
End Sub

Class itextlib:
'Class module
Sub Class_Globals

    Private nativeMe As JavaObject
   
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize

nativeMe = Me

End Sub

Public Sub createPdf(mystring As String) As Byte()

    Dim fn As String = "Belinda.pdf"
    Dim c128bytes() As Byte
    c128bytes = nativeMe.RunMethod("createPdf", Array(fn, mystring))
    Return c128bytes

End Sub

#If Java


import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.Barcode;
import com.itextpdf.text.pdf.Barcode128;
import com.itextpdf.text.pdf.Barcode39;
import com.itextpdf.text.pdf.BarcodeCodabar;
import com.itextpdf.text.pdf.BarcodeDatamatrix;
import com.itextpdf.text.pdf.BarcodeEAN;
import com.itextpdf.text.pdf.BarcodeEANSUPP;
import com.itextpdf.text.pdf.BarcodeInter25;
import com.itextpdf.text.pdf.BarcodePDF417;
import com.itextpdf.text.pdf.BarcodePostnet;
import com.itextpdf.text.pdf.BarcodeQRCode;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;


import java.io.File;
import java.io.FileOutputStream;

 

   public byte[] createPdf(String filename, String mystring) throws IOException, DocumentException {
       

        String configFilePath = new File(System.getProperty("user.dir")).getParent() + "/ItextBarcodes/";
       
        // step 1
        Document document = new Document(new Rectangle(340, 842));
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(configFilePath + filename));
        // step 3
        document.open();
        document.addHeader("Johan", "My Barcodes");
        document.addTitle("Hello Barcodes");
        document.addCreationDate();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
   
         
        Barcode128 uccEan128 = new Barcode128();
        uccEan128.setCodeType(Barcode.CODE128_UCC);
        uccEan128.setCode(mystring);

        document.add(uccEan128.createImageWithBarcode(cb, BaseColor.BLUE,
                BaseColor.BLACK));
               
        String bCode;
        if (uccEan128.getCodeType() == uccEan128.CODE128_RAW) {
            int idx = uccEan128.getCode().indexOf('\uffff');
            if (idx >= 0)
                bCode =  uccEan128.getCode().substring(0, idx);
            else
                bCode = uccEan128.getCode();
        }
        else {
            bCode = uccEan128.getRawText(uccEan128.getCode(), uccEan128.getCodeType() == uccEan128.CODE128_UCC);
        }
        int len = bCode.length();
        int fullWidth = (len + 2) * 11 + 2;
        byte bars[] = uccEan128.getBarsCode128Raw(bCode);
   
        document.close();
       
        return bars;        
}

#End If
 

Attachments

  • LGSBarcode.zip
    3.7 KB · Views: 69
  • Like
Reactions: LGS
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
Change AppStart code to the below and then get:

1654950579744.png


Change code in AppStart:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.SetFormStyle("UNIFIED")
    MainForm.RootPane.LoadLayout("main") 'Load the layout file.
    MainForm.Show
'    MainForm.BackColor = fx.Colors.ARGB(100,0,0,255)
    
    itl.Initialize
    
    Dim mystring As String = "(01)00000090311314(10)ABC123(15)060916"
    
 
    Dim mybytes() As Byte
    mybytes = itl.createPdf(mystring)
    For i = 0 To mybytes.Length - 1
        Log(mybytes(i))
    Next
    
    
    Dim barwidth As Double = 2dip
    Dim lft As Double = 10dip
    For i = 0 To mybytes.Length - 1
        If i Mod 2 = 0 Then
            Canvas1.DrawRect(lft, 10dip, barwidth * mybytes(i), 80dip, fx.Colors.Black, True, 0)
        Else
            Canvas1.DrawRect(lft, 10dip, barwidth * mybytes(i), 80dip, fx.Colors.White, True, 0)
        End If
        lft = lft + barwidth * mybytes(i)
    Next   
    
    Canvas1.DrawText(mystring, Canvas1.Width/2, 110dip, fx.DefaultFont(12), fx.Colors.Black, "CENTER")
    

    Label1.Text = ""
    

    
End Sub
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
it looks like @JohanSchoeman is inching you closer šŸ‘. let me just mention some research/testing results i've found:
you can't get the pixel data from an Image created with createImageWithBarcode(). and, for whatever reason, barcode128
does not have a plain createimage() method (pdf417, for example, does). the only type of createimage() method is
createAwtImage(), which is not supported by android.
there are methods relating to Image creation from either an existing Image or from a file, but to create an Image (eg jpeg) from
an existing Image, you have to have its data (bytes) ...

one more thing: when you tried to generate a GS1 barcode with zxing, did you have the GS1 setting on? i never use code128, so i don't know about size ratio's and other properties pertaining to other code types, but i set zxing's GS1 format on and generate a code with your text. is it a GS1?
 

Attachments

  • 1.png
    1.png
    86.9 KB · Views: 84
  • gs128.png
    gs128.png
    1.2 KB · Views: 89
Last edited:
Upvote 0
Top