Use a2png for png generation

docker-smtp
Marcin Kulik 7 years ago
parent 08ab2b6b62
commit ab77708b42

@ -11,11 +11,11 @@ class AsciicastImageGenerator
def generate(asciicast)
Dir.mktmpdir do |dir|
page_path = "#{dir}/asciicast.html"
asciicast_url = asciicast.file.absolute_url
image_path = "#{dir}/#{asciicast.image_filename}"
time = asciicast.snapshot_at || asciicast.duration / 2
generate_html_file(asciicast, page_path)
generate_png_file(page_path, image_path)
generate_png_file(asciicast_url, image_path, time)
image_width, image_height = get_size(image_path)
update_asciicast(asciicast, image_path, image_width, image_height)
@ -24,18 +24,8 @@ class AsciicastImageGenerator
private
def generate_html_file(asciicast, path)
html = template_renderer.render_to_string(
template: 'asciicasts/screenshot.html.slim',
layout: 'screenshot',
locals: { page: BareAsciicastPagePresenter.build(asciicast) },
)
File.open(path, 'w') { |f| f.write(html) }
end
def generate_png_file(page_path, image_path)
rasterizer.generate_image(page_path, image_path, 'png', '.asciinema-player', PIXEL_DENSITY)
def generate_png_file(asciicast_url, image_path, time)
rasterizer.generate_image(asciicast_url, image_path, time)
end
def get_size(image_path)

@ -2,13 +2,13 @@ require 'open3'
class Rasterizer
BINARY_PATH = (Rails.root + "bin" + "rasterize").to_s
BINARY_PATH = (Rails.root + "a2png" + "a2png.sh").to_s
def generate_image(page_path, image_path, format, selector, scale)
o, e, t = Open3.capture3("#{BINARY_PATH} #{page_path} #{image_path} #{format} #{selector} #{scale}")
def generate_image(asciicast_url, out_path, time)
o, e, t = Open3.capture3("#{BINARY_PATH} #{asciicast_url} #{out_path} #{time}")
if t.exitstatus != 0
raise RuntimeError, "Couldn't generate image from #{page_path}:\n#{o}\n#{e}"
raise RuntimeError, "Couldn't generate image from #{asciicast_url}:\n#{o}\n#{e}"
end
end

@ -1,78 +0,0 @@
#!/usr/bin/env phantomjs
var system = require('system');
if (system.args.length < 6) {
console.log("usage: " + system.args[0] + " <url> <filename> <format> <selector> <scale>");
console.log(" ex: " + system.args[0] + " page.html page.png png 'body > div' 2");
phantom.exit(1);
}
var url = system.args[1];
var filename = system.args[2];
var format = system.args[3];
var selector = system.args[4];
var scale = parseInt(system.args[5], 10);
var page = require('webpage').create();
page.viewportSize = { width: 9999, height: 9999 };
page.zoomFactor = scale;
page.onConsoleMessage = function(msg) {
console.log('console.log: ' + msg);
};
page.onError = function(msg, trace) {
console.log('Script error: ' + msg);
phantom.exit(1);
}
page.onResourceError = function(resourceError) {
console.log('Unable to load resource (#' + resourceError.id + 'URL:' + resourceError.url + ')');
console.log('Error code: ' + resourceError.errorCode + '. Description: ' + resourceError.errorString);
phantom.exit(1);
};
page.open(url, function(status) {
if (status !== "success") {
console.log("Failed to load " + url);
phantom.exit(1);
}
var rect = page.evaluate(function(selector) {
// Alternative to zoomFactor:
//
// /* scale the whole body */
// document.body.style.webkitTransform = "scale(2)";
// document.body.style.webkitTransformOrigin = "0% 0%";
// /* fix the body width that overflows out of the viewport */
// document.body.style.width = "50%";
//
// It has small issue with letter spacing though.
var elements = document.querySelectorAll(selector);
if (elements.length > 0) {
return elements[0].getBoundingClientRect();
}
}, selector);
if (!rect) {
console.log("Couldn't get geometry of requested DOM element");
phantom.exit(1);
return;
}
page.clipRect = {
left: rect.left * scale,
top: rect.top * scale,
width: rect.width * scale,
height: rect.height * scale
};
page.render(filename, { format: format });
phantom.exit(0);
});
// vim: ft=javascript

@ -24,6 +24,8 @@ else
echo "warning: sudo failed, not compiling libtsm and terminal binary"
fi
sudo apt-get install -y pngquant
if [ ! -e config/database.yml ]; then
cp config/database.yml.example config/database.yml
fi

@ -0,0 +1,17 @@
{
"version": 1,
"width": 96,
"height": 26,
"duration": 11.146430015564,
"command": "/bin/bash",
"title": "bashing :)",
"env": {
"TERM": "screen-256color",
"SHELL": "/bin/zsh"
},
"stdout": [
[1.234567, "foo \u001b[41mbar\u001b[32m"],
[5.678987, "baz qux"],
[3.456789, "żółć jaźń"]
]
}

@ -6,7 +6,13 @@ describe AsciicastImageGenerator, needs_phantomjs_2_bin: true do
let(:template_renderer) { ApplicationController.new }
describe '#generate' do
let(:asciicast) { create(:asciicast, theme_name: 'tango') }
let(:asciicast) {
create(
:asciicast,
theme_name: 'tango',
file: Asciinema::FixtureHelpers.fixture_file('1/screenshot.json', 'application/json')
)
}
def rgb(color)
[ChunkyPNG::Color.r(color), ChunkyPNG::Color.g(color), ChunkyPNG::Color.b(color)]
@ -20,17 +26,17 @@ describe AsciicastImageGenerator, needs_phantomjs_2_bin: true do
png = ChunkyPNG::Image.from_file(asciicast.image.path)
# make sure there are black-ish borders
expect(rgb(png[1, 1])).to eq([18, 19, 20])
expect(rgb(png[png.width - 2, png.height - 2])).to eq([18, 19, 20])
expect(rgb(png[1, 1])).to eq([17, 19, 20])
expect(rgb(png[png.width - 2, png.height - 2])).to eq([17, 19, 20])
# check content color (blue background)
expect(rgb(png[15, 15])).to eq([0, 175, 255])
# check content color (red-ish text background)
expect(rgb(png[93, 15])).to eq([221, 60, 105])
# make sure white SVG play icon is rendered correctly
expect(rgb(png[png.width / 2, (png.height / 2) - 10])).to eq([255, 255, 255])
# make sure PowerlineSymbols are rendered
expect(rgb(png[144, 795])).to eq([0, 95, 255])
expect(rgb(png[114, 28])).to eq([78, 191, 34])
end
it 'sets image_width and image_height on the asciicast' do

Loading…
Cancel
Save