Skip to content

Commit

Permalink
Initial image implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
svoboda-jan committed Jun 10, 2016
0 parents commit 67e2a01
Show file tree
Hide file tree
Showing 13 changed files with 306 additions and 0 deletions.
69 changes: 69 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so

# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip

# Logs and databases #
######################
*.log
*.sql
*.sqlite
*.sqlite3

# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Rails
*.rbc
*.sassc
.sass-cache
capybara-*.html
.rspec
/log
/tmp
/db/*.sqlite3
/public/system
/coverage/
/spec/tmp
**.orig
rerun.txt
pickle-email-*.html
config/initializers/secret_token.rb
config/secrets.yml

## Environment normalisation:
/.bundle
/vendor/bundle

# these should all be checked in to normalise the environment:
# Gemfile.lock, .ruby-version, .ruby-gemset

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc

pkg/*
Gemfile.lock
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in escpos-image.gemspec
gemspec
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Escpos-image

A ruby implementation of ESC/POS (thermal) printer image command specification.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'escpos-image'
```

And then execute:

$ bundle

Or install it yourself as:

$ gem install escpos-image

## Usage

```ruby
@printer = Escpos::Printer.new

image = Escpos::Image.new 'path/to/image.png'
# to use automatic conversion to monochrome format (requires mini_magick gem) use:
image = Escpos::Image.new 'path/to/image.png', convert_to_monochrome: true

@printer.write image.to_escpos

@printer.to_escpos # returns ESC/POS data ready to be sent to printer
# on linux this can be piped directly to /dev/usb/lp0
# with network printer sent directly to printer socket
# with serial port printer it can be sent directly to the serial port

@printer.to_base64 # returns base64 encoded ESC/POS data

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/escpos/escpos-image.

1. Fork it ( https://github.com/escpos/escpos-image/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require "bundler/gem_tasks"
task :default => :spec
14 changes: 14 additions & 0 deletions bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env ruby

require "bundler/setup"
require "escpos/image"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start

require "irb"
IRB.start
8 changes: 8 additions & 0 deletions bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -vx

bundle install

# Do any other automated setup that you need to do here
30 changes: 30 additions & 0 deletions escpos-image.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'escpos/image'

Gem::Specification.new do |spec|
spec.name = "escpos-image"
spec.version = Escpos::Image::VERSION
spec.authors = ["Jan Svoboda"]
spec.email = ["[email protected]"]
spec.summary = %q{A ruby implementation of ESC/POS (thermal) printer image command specification.}
spec.description = %q{A ruby implementation of ESC/POS (thermal) printer image command specification.}
spec.homepage = "https://github.com/escpos/escpos-image"
spec.license = "MIT"

spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]

spec.required_ruby_version = ">= 1.9"

spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"

spec.add_development_dependency "minitest", "~> 5.4.2"

spec.add_dependency "escpos"
spec.add_dependency "chunky_png"
end
9 changes: 9 additions & 0 deletions lib/escpos/helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Escpos
module Helpers

def image(path, opts = {})
Image.new(path, opts).to_escpos
end

end
end
84 changes: 84 additions & 0 deletions lib/escpos/image.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module Escpos
class Image

VERSION = "0.0.1"

def initialize(image_path, opts = {})
if opts.fetch(:convert_to_monochrome, false)
require_mini_magick!
image = convert_to_monochrome(image_path, opts)
@image = ChunkyPNG::Image.from_file(image.path)
else
@image = ChunkyPNG::Image.from_file(image_path)
end

unless @image.width % 8 == 0 && @image.height % 8 == 0
raise ArgumentError.new("Image width and height must be a multiple of 8.")
end
end

def to_escpos
bits = []
mask = 0x80
i = 0
temp = 0

0.upto(@image.height - 1) do |y|
0.upto(@image.width - 1) do |x|
r, g, b, a =
ChunkyPNG::Color.r(@image[x, y]),
ChunkyPNG::Color.g(@image[x, y]),
ChunkyPNG::Color.b(@image[x, y]),
ChunkyPNG::Color.a(@image[x, y])
px = (r + g + b) / 3
raise ArgumentError.new("PNG images with alpha are not supported.") unless a == 255
value = px > 128 ? 255 : 0
value = (value << 8) | value
temp |= mask if value == 0
mask = mask >> 1
i = i + 1
if i == 8
bits << temp
mask = 0x80
i = 0
temp = 0
end
end
end

[
Escpos.sequence(IMAGE),
[@image.width / 8, @image.height ].pack("SS"),
bits.pack("C*")
].join
end

private

def require_mini_magick!
unless defined?(MiniMagick)
begin
require 'mini_magick'
rescue LoadError => e
raise 'Required options need the mini_magick gem installed.'
end
end
end

def convert_to_monochrome(image_path, opts = {})
image = MiniMagick::Image.open(image_path)
image.flatten
image.grayscale 'Rec709Luma'
if opts.fetch(:dither, true)
image.monochrome
else
image.monochrome '+dither'
end
if opts.fetch(:extent, true)
image.extent "#{(image.width/8.0).round*8}x#{(image.height/8.0).round*8}"
end
image
end

end
end
Binary file added test/fixtures/tux_alpha.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/tux_mono.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions test/lib/escpos/image_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require_relative '../../test_helper'

class TestPrinter < Minitest::Test
def setup
@printer = Escpos::Printer.new
end

def test_image
image_path = File.join(__dir__, '../../fixtures/tux_mono.png')
image = Escpos::Image.new image_path

@printer.write image.to_escpos
@printer.write "\n" * 10
@printer.cut!
#pp @printer.to_base64
assert_equal @printer.to_base64, 'G0AddjAAEACYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAAAAAAAAAAAAD///AAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAD////gAAAAAAAAAAAAAAAB////+AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAf////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAB//////gAAAAAAAAAAAAAA//////4AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAAf//////gAAAAAAAAAAAAAP//////4AAAAAAAAAAAAAD//////+AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAP//////8AAAAAAAAAAAAAD///////AAAAAAAAAAAAAA////D//wAAAAAAAAAAAAAP///Af/8AAAAAAAAAAAAAH4P/gB//AAAAAAAAAAAAAB8B/wAf/wAAAAAAAAAAAAAfAP8AD/8AAAAAAAAAAAAAHgD+AA//AAAAAAAAAAAAAB4AfgwH/4AAAAAAAAAAAAAeEHweB/+AAAAAAAAAAAAAHjh8Hwf/gAAAAAAAAAAAAA58fD8H/4AAAAAAAAAAAAAOfHw/B/+AAAAAAAAAAAAADnx+Pwf/gAAAAAAAAAAAAA5/w/8H/4AAAAAAAAAAAAAOPgB/B/+AAAAAAAAAAAAADjwAHw//gAAAAAAAAAAAAA8YAAcP/4AAAAAAAAAAAAAPsAAB//+AAAAAAAAAAAAAD8AAAD//gAAAAAAAAAAAAA+AAAAP/4AAAAAAAAAAAAAPAAAAB/+AAAAAAAAAAAAADgAAAAf/gAAAAAAAAAAAAAwAAADH/4AAAAAAAAAAAAAMwAADh/+AAAAAAAAAAAAAHmAABgf/gAAAAAAAAAAAAB4wABgP/4AAAAAAAAAAAAAfDABgH//AAAAAAAAAAAAAH4cBgDP/wAAAAAAAAAAAAB/g/gDD/+AAAAAAAAAAAAA/MAADA//gAAAAAAAAAAAAPwgADAH/8AAAAAAAAAAAAD8EADAB//AAAAAAAAAAAAB/AwBgAf/4AAAAAAAAAAAAfwDDgAD/+AAAAAAAAAAAAP4AAAAA//wAAAAAAAAAAAD+AAAAAP/+AAAAAAAAAAAB/gAAAAB//gAAAAAAAAAAAf4AAAAAf/8AAAAAAAAAAAP8AAAAAH//gAAAAAAAAAAH/AAAAAA//8AAAAAAAAAAD/wAAAAAP//gAAAAAAAAAA/4AAAAAB//4AAAAAAAAAAf+AAAAAAf//AAAAAAAAAAP/gAAAAAH//4AAAAAAAAAH/wAAAAAA///AAAAAAAAAD/8AAAAAAP//4AAAAAAAAA//AAAAAAB//+AAAAAAAAAf/gAAAAAAff/wAAAAAAAAP/4AAAAAAH7/+AAAAAAAAD/8AAAAAAA/f/gAAAAAAAB//AAAAAAAP7/8AAAAAAAA/vgAAAAAAB/f/gAAAAAAAP34AAAAAAAfz/4AAAAAAAH98AAAAAAAD+//AAAAAAAB+/AAAAAAAA/3/wAAAAAAA/vwAAAAAAAH8/+AAAAAAAP34AAAAAAAB/v/gAAAAAAH9+AAAAAAAAP5/8AAAAAAD+/AAAAAAAAD+f/AAAAAAA/vwAAAAAAAAfz/4AAAAAAfz4AAAAAAAAH8/+AAAAAAH9+AAAAAAAAA/P/wAAAAAB+fAAAAAAAAAP5/8AAAAAA/nwAAAAAAAAD+f/AAAAAAP78AAAAAAAAAfn/4AAAAAH8+AAAAAAAAAH5/+AAAAAB/PgAAAAAAAAB+f/gAAAAAfz4AAAAAAAAAPj/4AAAAAP88AAAAAAAAAD4//AAAAAD/PAAAAAAAAAA+P/wAAAAA/jwAAAAAAAAAHj/8AAAAAP48AAAAAAAAABx//AAAAAH+PAAAAAAAAAAMf/wAAAAB/zgAAAAAAAAAAH/8AAAAAf8YAAAAAAAAAAA//AAAAAH/GAAAAAAAAAA8D/wAAAAB/wgAAAAAAAAA54P8AAAAAf+IAAAAAAAAAIDx/AAAAAH/gAAAAAAAAAGAOPwAAAAB/8AAAAAAAAABAB58AAAAAf/AAAAAAAAAAwAPPAAAAAH/4AAAAAAAAAcADzwAAAAB//AAAAAAAAAfAAc4AAAAA4H4AAAAAAAAGYAPuAAAAAcAfAAAAAAAADGAD/gAAAAGAD8AAAAAAAAxgB/8AAAADAA/gAAAAAAAYMB+DwAAABgAH+AAAAAAAGDx/AMAAAA4AA/wAAAAAABgf/gBgAAAcAAH/AAAAAAAwD/gAYAAAeAAB/4AAAAAAMAfgADAAA+AAAP/AAAAAADAAAAAwAA+AAAD/4AAAAAAwAAAAMAAcAAAAf/AAAAAAMAAAABAAOAAAAH/4AAAAADAAAAAYADAAAAA/+AAAAAAwAAAAGABgAAAAP/wAAAAAMAAAABgAYAAAAB/8AAAAAGAAAAAMAGAAAAAf/gAAAABgAAAADABgAAAAD/4AAAAAYAAAAAYAYAAAAA/+AAAAAGAAAAADAGAAAAAH/gAAAABgAAAAA4BgAAAAA/wAAAAAYAAAAAGAYAAAAAH4AAAAAGAAAAAAwDAAAAAB4AAAAADgAAAAAMAwAAAAAOAAAAAAwAAAAABgMAAAAABgAAAAAMAAAAAAYDAAAAAAMAAAAADAAAAAAGBgAAAAABgAAAABgAAAAADgYAAAAAAcAAAAA4AAAAAAwGAAAAAADAAAAA+AAAAAA4BgAAAAAAcAAAA/gAAAAAcAwAAAAAAHwAAA/wAAAAAcAMAAAAAAA/AAB/8AAAAAcADAAAAAAAP/AH//AAAAAcAAwAAAAAAD/////wAAAAcAAOAAAAAAAf////8AAAAeAABgAAAAAAH////+AAAAOAAAMAAAAAAB/////gAAAGAAAB8AAAAAA/////4AAADAAAAH/wAAAAP/gAf/AAABgAAAAH/4AAAD4AAAAwAAAwAAAAAAfgAABgAAAAMAAAYAAAAAAAfAAA4AAAABgAAMAAAAAAAB8AAcAAAAAcAAOAAAAAAAAH4AeAAAAADAAHAAAAAAAAAP/+AAAAAAcAHgAAAAAAAAAf+AAAAAADwPgAAAAAAAAAAAAAAAAAAf/gAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAACgoKCgoKCgoKCh1WAA=='
end

def test_image_conversion
image_path = File.join(__dir__, '../../fixtures/tux_alpha.png')
image = Escpos::Image.new image_path, convert_to_monochrome: true

@printer.write image.to_escpos
@printer.write "\n" * 10
@printer.cut!
#pp @printer.to_base64
assert_equal @printer.to_base64, 'G0AddjAAEACYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAAAAAD//AAAAAAAAAAAAAAAAAAH//+AAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAP////AAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAB/////AAAAAAAAAAAAAAAB/////4AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAP/////wAAAAAAAAAAAAAAH/////+AAAAAAAAAAAAAAB//////gAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////4AAAAAAAAAAAAAA//////+AAAAAAAAAAAAAAf//////gAAAAAAAAAAAAAH//////8AAAAAAAAAAAAAB//////+AAAAAAAAAAAAAA///////wAAAAAAAAAAAAAH//////8AAAAAAAAAAAAAD///8H//AAAAAAAAAAAAAAfn/8A//wAAAAAAAAAAAAAPwf+AH/8AAAAAAAAAAAAAB4D/AA//gAAAAAAAAAAAAAcAfwAP/4AAAAAAAAAAAAAPAH8GB/8AAAAAAAAAAAAADwB/Dwf/AAAAAAAAAAAAAAY8Ph8H/4AAAAAAAAAAAAAPHj4/g/+AAAAAAAAAAAAADj4+P4f/AAAAAAAAAAAAAA4+Pj+D/4AAAAAAAAAAAAAHPue/h/8AAAAAAAAAAAAABz8Af4f/AAAAAAAAAAAAAAeeAB8P/4AAAAAAAAAAAAAHiAAHD/+AAAAAAAAAAAAAB/gAAe//AAAAAAAAAAAAAAfgAAA//wAAAAAAAAAAAAAHwAAAD/+AAAAAAAAAAAAABwAAAAf/gAAAAAAAAAAAAAcAAAAH/4AAAAAAAAAAAAAHQAAA4/+AAAAAAAAAAAAADmAAAYf/gAAAAAAAAAAAAA8wAA4H/4AAAAAAAAAAAAAPGAAID//AAAAAAAAAAAAAD44AcB//wAAAAAAAAAAAAA/B08Bj/8AAAAAAAAAAAAAP4LwAw//gAAAAAAAAAAAAH5wAB4H/4AAAAAAAAAAAAB+EAAgB//AAAAAAAAAAAAA/gwA4Af/wAAAAAAAAAAAAP4GAwAH/+AAAAAAAAAAAAH+A/wAA//wAAAAAAAAAAAB/AAgAAP/8AAAAAAAAAAAAfwAAAAD//gAAAAAAAAAAAP8AAAAAf/8AAAAAAAAAAAH+AAAAAH//gAAAAAAAAAAD/gAAAAA//4AAAAAAAAAAA/4AAAAAP//AAAAAAAAAAAf+AAAAAD//4AAAAAAAAAAP/AAAAAAf//AAAAAAAAAAH/wAAAAAH//4AAAAAAAAAD/4AAAAAA//+AAAAAAAAAA/+AAAAAAP//wAAAAAAAAAf/gAAAAAB//+AAAAAAAAAP/wAAAAAAff/wAAAAAAAAD/8AAAAAAH7/8AAAAAAAAB/+AAAAAAA/f/gAAAAAAAA/fgAAAAAAP7/8AAAAAAAAP/4AAAAAAB/f/AAAAAAAAH78AAAAAAAf7/4AAAAAAAD+/AAAAAAAD+/+AAAAAAAA/fgAAAAAAA/n/wAAAAAAAf/4AAAAAAAH9/+AAAAAAAH78AAAAAAAB///gAAAAAAD//AAAAAAAAP7/8AAAAAAA/PgAAAAAAAD+f/AAAAAAAf/4AAAAAAAAf3/wAAAAAAH58AAAAAAAAH9/+AAAAAAD+/AAAAAAAAB/P/gAAAAAA/vwAAAAAAAAP7/8AAAAAAfz4AAAAAAAAD+//AAAAAAH9+AAAAAAAAAfn/wAAAAAB/PgAAAAAAAAH5/+AAAAAA/3wAAAAAAAAB+f/gAAAAAP98AAAAAAAAAfn/4AAAAAH+fAAAAAAAAAD5/+AAAAAB/ngAAAAAAAAA+f/gAAAAAf54AAAAAAAAAPH/8AAAAAH+eAAAAAAAAADx/+AAAAAD/jgAAAAAAAAAA//wAAAAA/54AAAAAAAAAAH/8AAAAAH/MAAAAAAAAACof+AAAAAD/xAAAAAAAAAD/D/wAAAAA/8YAAAAAAAAAx+P8AAAAAP/EAAAAAAAAAYD5/AAAAAD/4AAAAAAAAAEAPPgAAAAA//AAAAAAAAADAB58AAAAAP/wAAAAAAAABwAPeAAAAAD/+AAAAAAAAB8AD3gAAAAA4P4AAAAAAAAZgA94AAAAAYB+AAAAAAAAMYAf8AAAAAOAH4AAAAAAADGAP/wAAAAHAA/gAAAAAABgwH6eAAAABgAP8AAAAAAAYOH8BwAAABwAB/gAAAAAAOD/8AMAAAAYAAP+AAAAAABAP+ABgAAA+AAD/gAAAAAAwB+AAYAAA+AAAf+AAAAAAMAAAAGAAA+AAAH/wAAAAADAAAAAwAAcAAAA/+AAAAAAwAAAAMAAOAAAAP/wAAAAAMAAAADAADAAAAB/8AAAAAHAAAAAwABgAAAAf/gAAAAAwAAAAGAAYAAAAD/4AAAAAYAAAABgAGAAAAA/+AAAAAHAAAAAcABgAAAAH/wAAAAAgAAAADgAYAAAAA/8AAAAAYAAAAAYAGAAAAAP/AAAAAGAAAAADABgAAAAB/gAAAABgAAAAAYAYAAAAAPwAAAAAYAAAAAGAGAAAAABwAAAAAMAAAAABwAwAAAAAcAAAAADAAAAAAMAIAAAAADgAAAAAwAAAAADAHAAAAAAYAAAAAcAAAAAAwBgAAAAADAAAAAGAAAAAAYAYAAAAAA4AAAAHgAAAAAOAGAAAAAAHAAAAH4AAAAAHADgAAAAAA8AAAH8AAAAAPgAwAAAAAAPwAAP/AAAAAHgAMAAAAAAB/wCf/wAAAAPgADAAAAAAAf////8AAAAHgAAwAAAAAAD/////AAAAHgAAGAAAAAAB/////gAAAHgAABwAAAAAAP////8AAABwAAAPgAAAAAH////+AAABwAAAA/+AAAAB/9qf/wAAA4AAAAB//AAAAfgAAGsAAAcAAAAAAH+AAAOAAAADAAAGAAAAAAAH4AAHAAAAAYAAHAAAAAAAAHgABgAAAAHAADgAAAAAAAA+ADwAAAAAwABwAAAAAAAAB/v4AAAAAHABwAAAAAAAAAH/4AAAAAA8B4AAAAAAAAAABAAAAAAAH/4AAAAAAAAAAAAAAAAAAAP4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoKCgoKCgoKCh1WAA=='
end

end
9 changes: 9 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#$VERBOSE = true

require 'minitest/autorun'
#require 'minitest/pride'
require 'pp'

require 'escpos'
require 'chunky_png'
require File.expand_path('../../lib/escpos/image.rb', __FILE__)

0 comments on commit 67e2a01

Please sign in to comment.