Bitmap issues

Breakout boards, sensors, Drawdio, Game of Life, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Bitmap issues

Postby davidcx » Mon Jan 16, 2012 3:04 pm

Having fun with the printer, but a couple of questions regarding bitmaps:

1) Has anyone succeeded in downloading bitmaps into memory using GS *? I just get a spew of random characters on the printer. It's possible my code is borked, but since my DC2 * code works fine, I suspect it's more likely a documentation problem.

2) Are others experiencing white horizontal lines? They are highly visible in images, but also sometimes noticeable in text. I've tried experimenting with both ESC 7 (printing dots, heating time, heating interval) and DC2 # (printing density and break time), but I can't find a solution that removes the lines without overexposing the image:

377989_2888034473660_1044126991_32970184_1369101081_n.jpg
Thermal printer white lines.
377989_2888034473660_1044126991_32970184_1369101081_n.jpg (82.13 KiB) Viewed 520 times


-davidc
davidcx
 
Posts: 4
Joined: Mon Nov 14, 2011 7:25 pm

Re: Bitmap issues

Postby commy » Fri Feb 17, 2012 4:49 pm

Hi davidc

Nice project! Could you please share the code of how you print those nice grayscale photos?

Thanks.
commy
 
Posts: 11
Joined: Fri Jan 25, 2008 6:11 pm

Re: Bitmap issues

Postby davidcx » Mon Feb 20, 2012 5:15 pm

Sure, it's a bannedïve implementation of Floyd-Steinberg dithering, with a first pass to get the average brightness to calculate the threshold for black and white. As a prototype, it's highly inefficient and I haven't optimised to take account that the colours are only black and white. Let me know if you get horizontal stripes too!

Code: Select all
package net.davidc.thermal;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;

import gnu.io.CommPortIdentifier;

/**
* @author David Croft (davidc.net)
* @version $Id: FloydSteinbergDither.java 45 2012-01-16 20:14:04Z david $
*/
public class FloydSteinbergDither
{
  private FloydSteinbergDither()
  {
  }

  public static float getAverageBrightness(BufferedImage srcImage)
  {
    long accum = 0;

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

    for (int y = 0; y < height; ++y) {
      for (int x = 0; x < width; ++x) {
        int srcColour = srcImage.getRGB(x, y);
        accum += (srcColour & 0xff) + (srcColour >> 8 & 0xff) + (srcColour >> 16 & 0xff);
      }
    }

    return (float) (accum / (width * height * 3.0 * 255));
  }

  // NB: Will corrupt source image!
  public static BufferedImage dither(BufferedImage srcImage, float threshold)
  {
    int width = srcImage.getWidth();
    int height = srcImage.getHeight();

    BufferedImage destImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);

    for (int y = 0; y < height; ++y) {
      for (int x = 0; x < width; ++x) {

        int srcColour = srcImage.getRGB(x, y);

        float brightness = ((srcColour & 0xff) + (srcColour >> 8 & 0xff) + (srcColour >> 16 & 0xff)) / (3.0f * 255);
        int destColour = brightness >= threshold ? 0xffffffff : 0xff000000;

        destImage.setRGB(x, y, destColour);

        // TODO simplify, since we know it's either 0xff or 0x00, in all channels
        int redError = (srcColour & 0xff) - (destColour & 0xff);
        int greenError = (srcColour >> 8 & 0xff) - (destColour >> 8 & 0xff);
        int blueError = (srcColour >> 16 & 0xff) - (destColour >> 16 & 0xff);

        if (x + 1 < width) {
          diffuseError(srcImage, x + 1, y + 0, (redError * 7) >> 4, (greenError * 7) >> 4, (blueError * 7) >> 4);
        }
        if (y + 1 < height) {
          if (x - 1 >= 0) {
            diffuseError(srcImage, x - 1, y + 1, (redError * 3) >> 4, (greenError * 3) >> 4, (blueError * 3) >> 4);
          }
          diffuseError(srcImage, x + 0, y + 1, (redError * 5) >> 4, (greenError * 5) >> 4, (blueError * 5) >> 4);
          if (x + 1 < width) {
            diffuseError(srcImage, x + 1, y + 1, (redError * 1) >> 4, (greenError * 1) >> 4, (blueError * 1) >> 4);
          }
        }
      }
    }

    return destImage;
  }

  private static void diffuseError(BufferedImage srcImage, int x, int y, int redError, int greenError, int blueError)
  {
    // already checked by caller
//        if (x < 0 || x >= srcImage.getWidth() || y >= srcImage.getHeight()) { // y can never be < 0
//      return;
//    }

    int colour = srcImage.getRGB(x, y);

    int red = (colour & 0xff) + redError;
    int green = (colour >> 8 & 0xff) + greenError;
    int blue = (colour >> 16 & 0xff) + blueError;

    if (red < 0) red = 0;
    else if (red > 255) red = 255;
    if (green < 0) green = 0;
    else if (green > 255) green = 255;
    if (blue < 0) blue = 0;
    else if (blue > 255) blue = 255;

    colour = 0xff000000 | red | (green << 8) | (blue << 16);

    srcImage.setRGB(x, y, colour);
  }

  public static void main(String[] args) throws Exception
  {
    BufferedImage src = ImageIO.read(new File("lenna.png"));
//    src = src.getSubimage(64, 0, 384, 512);

    float averageBrightness = getAverageBrightness(src);
    System.out.println("averageBrightness = " + averageBrightness);

    BufferedImage dest = dither(src, averageBrightness);

    ImageIO.write(dest, "PNG", new File("lenna-out.png"));
//    printImage(dest);
  }

  private static void printImage(BufferedImage dest) throws Exception
  {
    ThermalPrinter printer = new ThermalPrinter(CommPortIdentifier.getPortIdentifier("COM6"));
    try {
      printer.reset();
      printer.setPrintingDensity(2, 0);
      printer.printArbitraryHeightBitmap(dest);
    }
    finally {
      printer.close();
    }
  }
}
davidcx
 
Posts: 4
Joined: Mon Nov 14, 2011 7:25 pm


Return to Other Adafruit products

Who is online

Users browsing this forum: No registered users and 3 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [103]

Raspberry Pi[80]
 
FLORA[23]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[11]
Arduino[60]
 
NETduino[14]
 
BeagleBone[24]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[33]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[8]


 
Breakout Boards[33]
LCDs & Displays[48]
Components & Parts[69]
Batteries & Power[49]
EL Wire/Tape/Panel[52]
LEDs[109]
 
Wireless[14]
Cables[61]
 
Lasers[6]
Sensors/Parts[145]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[70]
 
iDevices[13]
Tools[71]
 
Wearables[39]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[24]


 
Stickers[41]
 
Skill badges[55]
 
Books[25]
 
Circuit Playground[7]
 
Gift Certificates[4]