Skip to content

Instantly share code, notes, and snippets.

@trevarj
Last active September 27, 2024 03:14
Show Gist options
  • Save trevarj/1255e5cbc08fb3f79c3f255e25989a18 to your computer and use it in GitHub Desktop.
Save trevarj/1255e5cbc08fb3f79c3f255e25989a18 to your computer and use it in GitHub Desktop.
Convert Unicode to Image and Compress for ZPL - Zebra (^GF for ZPL)
/**
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
________________________________________________________________________
* The purpose of this is to take some unicode text
* and create an image out of it so that we can
* print it on an old Zebra label printer that
* doesn't have enough memory for unicode fonts.
*
* The string that is returned can be embedded directly into
* a ZPL script and sent to the printer.
*
* After many searches and scouring of manuals,
* and with the help of others, I finally got this working well.
*
* Hopefully this can help someone else and that they
* find it faster than it took me to piece it together.
*
* Obviously I'm leaving out all the imports and stuff.
*/
public String textToZ64CompressedImage(String input){
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = img.createGraphics();
Font font = new Font(g2d.getFont().getName(), Font.PLAIN, 28);
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
int width = fm.stringWidth(input);
int height = fm.getHeight();
img = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
g2d = img.createGraphics();
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.WHITE);
g2d.setFont(font);
g2d.drawString(input, 0, fm.getAscent());
g2d.dispose();
// LZ77 compression
ByteArrayOutputStream compressedImage = new ByteArrayOutputStream();
DataBufferByte dataBufferByte = (DataBufferByte)img.getRaster().getDataBuffer();
DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(compressedImage);
try
{
deflaterOutputStream.write(dataBufferByte.getData(), 0, dataBufferByte.getData().length);
deflaterOutputStream.finish();
}
catch (IOException e)
{
LOG.debug("Couldn't compress image for printing.");
return "I/O error";
}
// without compression
// byte[] encodedBytesImage = Base64.getMimeEncoder().encode(dataBufferByte.getData());
byte[] encodedBytesImage = Base64.getMimeEncoder().encode(compressedImage.toByteArray());
String crcString = getCRCHexString(encodedBytesImage);
String bytesPerRow = String.valueOf(dataBufferByte.getData().length / height);
int binaryByteCount = (width * height) / 8;
String encodedAscii = "^GFA," + binaryByteCount + "," + binaryByteCount + "," + bytesPerRow + ",:Z64:" + new String(encodedBytesImage, Charsets.US_ASCII) + ":" + crcString;
try
{
compressedImage.close();
}
catch (IOException e)
{
LOG.error("Couldn't close image output stream.");
}
return encodedAscii;
}
/**
* Reads in a sequence of bytes and prints out its 16 bit
* Cylcic Redundancy Check (CRC-CCIIT 0xFFFF).
*
* 1 + x + x^5 + x^12 + x^16 is irreducible polynomial.
*
*/
private static String getCRCHexString(byte[] bytes)
{
int crc = 0x0000; // initial value
int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
for (byte b : bytes)
{
for (int i = 0; i < 8; i++)
{
boolean bit = ((b >> (7 - i) & 1) == 1);
boolean c15 = ((crc >> 15 & 1) == 1);
crc <<= 1;
if (c15 ^ bit)
{
crc ^= polynomial;
}
}
}
crc &= 0xffff;
return Integer.toHexString(crc);
}
@dv996coding
Copy link

OK, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment