Permalink
Browse files

Include printing from a Stream instance.

This allows us to print from (for example) an SD file, or an Ethernet client, without
needing to require either.

The new  method expects the width and height to be
encoded in the first four bytes of the stream - see  for an example.
  • Loading branch information...
lazyatom committed Mar 8, 2012
1 parent 9172981 commit 82dacbdd6c3ea6a32fe123cb1ff17b6810a4c330
Showing with 74 additions and 9 deletions.
  1. +28 −7 Thermal.cpp
  2. +2 −2 Thermal.h
  3. +44 −0 image_to_file
View
@@ -261,17 +261,38 @@ void Thermal::printBitmap(int w, int h, const uint8_t *bitmap) {
if (w > 384) return; // maximum width of the printer
for (int rowStart=0; rowStart < h; rowStart += 256) {
int chunkHeight = ((h - rowStart) > 255) ? 255 : (h - rowStart);
printBitmapChunk(w, chunkHeight, rowStart*(w/8), bitmap);
writeBytes(18, 42);
writeBytes(chunkHeight, w/8);
for (int i=0; i<((w/8)*chunkHeight); i++) {
PRINTER_PRINT(pgm_read_byte(bitmap + (rowStart*(w/8)) + i));
}
}
}
void Thermal::printBitmapChunk(int w, uint8_t h, int offset, const uint8_t *bitmap) {
writeBytes(18, 42);
writeBytes(h, w/8);
for (int i=0; i<((w/8)*h); i++) {
PRINTER_PRINT(pgm_read_byte(bitmap + offset + i));
void Thermal::printBitmap(int w, int h, Stream *stream) {
if (w > 384) return; // maximum width of the printer
for (int rowStart=0; rowStart < h; rowStart += 256) {
int chunkHeight = ((h - rowStart) > 255) ? 255 : (h - rowStart);
writeBytes(18, 42);
writeBytes(chunkHeight, w/8);
for (int i=0; i<((w/8)*chunkHeight); i++) {
PRINTER_PRINT((uint8_t)stream->read());
}
}
}
};
void Thermal::printBitmap(Stream *stream) {
uint8_t tmp;
uint16_t width, height;
tmp = stream->read();
width = (stream->read() << 8) + tmp;
tmp = stream->read();
height = (stream->read() << 8) + tmp;
printBitmap(width, height, stream);
};
// Take the printer offline. Print commands sent after this will be
// ignored until `online` is called
View
@@ -81,6 +81,8 @@ class Thermal : public Print {
void setBarcodeHeight(int val);
void printBitmap(int w, int h, const uint8_t *bitmap);
void printBitmap(int w, int h, Stream *stream);
void printBitmap(Stream *stream);
// ??
void tab();
@@ -100,8 +102,6 @@ class Thermal : public Print {
void setPrintMode(uint8_t mask);
void unsetPrintMode(uint8_t mask);
void printBitmapChunk(int w, uint8_t h, int offset, const uint8_t *bitmap);
int _RX_Pin;
int _TX_Pin;
View
@@ -0,0 +1,44 @@
#!/usr/bin/env ruby
=begin
This script uses imagemagick and RMagick to produce a dithered version of an
image, and then produces a cpp file containing an array of bytes suitable
for printing.
The cpp files also contain a comment which is useful to visualise the printed
output; I suggest you open it in a text editor and shrink the fontsize until
each row of characters fits on the screen without wrapping.
=end
require "rubygems"
require "bundler/setup"
require "RMagick"
include Magick
require 'optparse'
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [options] <input_image> [<output_name>]"
opts.on("-s", "--skip-header", "Don't include the dimensions header") do |s|
options[:skip_header] = true
end
end.parse!
path = ARGV[0]
output_name = ARGV[1] || File.join(File.dirname(path), File.basename(path).split(".")[0...-1].join)
`convert -colorspace Gray -ordered-dither o2x2 #{path} #{output_name}.bmp`
img = ImageList.new("#{output_name}.bmp")[0]
bits = []
width = img.columns
height = img.rows
img.each_pixel { |pixel, _, _| bits << (pixel.red > 0 ? 0 : 1) }
bytes = []; bits.each_slice(8) { |s| bytes << ("0" + s.join).to_i(2) }
File.open(output_name, "w") do |f|
f.write([width,height].pack("SS")) unless options[:skip_header]
f.write(bytes.pack("C*"))
end
puts "wrote #{bytes.length} bytes to #{output_name}"

3 comments on commit 82dacbd

@kabrio

This comment has been minimized.

Show comment
Hide comment
@kabrio

kabrio May 2, 2013

See where for example??

How do you encode width and height into the first four bytes.

Explanations would be superhelpful!

kabrio replied May 2, 2013

See where for example??

How do you encode width and height into the first four bytes.

Explanations would be superhelpful!

@lazyatom

This comment has been minimized.

Show comment
Hide comment
@lazyatom

lazyatom May 7, 2013

Owner

Apologies, it looks like the commit message got screwed up. The last line should read:

The new printBitmap(Stream *stream) method expects the width and height to be
encoded in the first four bytes of the stream - see image_to_file for an example.

In other words, the Ruby script at the bottom of this commit includes the example of encoding the width and height.

Owner

lazyatom replied May 7, 2013

Apologies, it looks like the commit message got screwed up. The last line should read:

The new printBitmap(Stream *stream) method expects the width and height to be
encoded in the first four bytes of the stream - see image_to_file for an example.

In other words, the Ruby script at the bottom of this commit includes the example of encoding the width and height.

@kabrio

This comment has been minimized.

Show comment
Hide comment
@kabrio

kabrio May 7, 2013

great, thanks!

kabrio replied May 7, 2013

great, thanks!

Please sign in to comment.