Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
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...
commit 82dacbdd6c3ea6a32fe123cb1ff17b6810a4c330 1 parent 9172981
@lazyatom authored
Showing with 74 additions and 9 deletions.
  1. +28 −7 Thermal.cpp
  2. +2 −2 Thermal.h
  3. +44 −0 image_to_file
View
35 Thermal.cpp
@@ -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
4 Thermal.h
@@ -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
44 image_to_file
@@ -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

See where for example??

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

Explanations would be superhelpful!

@lazyatom
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.

@kabrio

great, thanks!

Please sign in to comment.
Something went wrong with that request. Please try again.