Open gatzke opened 3 years ago
Half carriage has to be supported by the terminal, as far as I can tell most terminal emulators do not support it. Instead one can use HTML. jp2a does support HTML output and with some CSS it can be displayed like half carriage would look. Bash script (3 arguments: first is where the HTML file should be stored, the other two are the input images):
#!/bin/bash
if [ $# -eq 3 ]
then
if [ -e "$1" ]
then
echo "$1 already exists"
else
echo "<!DOCTYPE html>
<html>
<head>
<meta charset=\"utf-8\">
<title>jp2a converted image half carriage</title>
<style>
body {
background-color: black;
}
.ascii {
font-family: Courier;
color: white;
font-size: 8pt;
line-height: 1.2em;
font-weight: bold;
}
.first {
position: fixed;
top: 0;
left: 0;
}
.second {
position: fixed;
top: 0.6em;
left: 0;
}
</style>
</head>
<body>
<div class='ascii first'><pre>" > "$1"
jp2a --html --html-raw "$2" >> "$1"
echo "</pre>
</div>
<div class='ascii second'><pre>" >> "$1"
jp2a --html --html-raw "$3" >> "$1"
echo "</pre>
</div>
</body>
</html>" >> "$1"
fi
else
echo "Usage: $0 <output> <input A> <input B>"
fi
The second image appears 0.6em below the first, where 0.6em is half the line-height.
Thanks so much!
It looks like your (genius) script doubles the ASCII image with overlap. I don't think it renders the optimal overlapped image, but I could be wrong.
Rendering two separate ASCII files may be tricky. Normal jp2a can analyze chunks of the image since they are all independent. If characters overlap, other parts of time output are affected. The output optimization becomes trickier.
Put a half horizontal space in one output file and then every output character affects the overall rendering. I think some typewriters had that level of horizontal spacing control back in the day.
Thanks again!
Rabbit demos with your script:
Worked some awful Matlab code to run simple random optimization of the ASCII overlap image. It does not shift the odd rows half a column but I may add that too.
Warning, this code is turrible. ;-)
close all nx=21 ny=27 C=64+randi(26,6,6)
C=59+randi(31,6,6)
%char(32:1:126) C=31+randi(126-32,ny,nx)
C=zeros(ny,nx)+32 best=99999
h=imread('rabbit.jpg'); hh=h(:,:,1)+h(:,:,2)+h(:,:,3); %whos h hh spy(hh>225) spy(hh(250:350,100:200)>225) spy(hh(150:450,100:400)>225) a=hh(150:450,100:400)>225;
for k=1:3000 % k=1
%close all
subplot(2,1,1);subplot(1,1,1) f=figure(1); pos=get(f,'Position'); %set(f,'Position',[1200 pos(2) pos(3) pos(4)])
axis off axis([0 1 0 1]); fs=18; % Draw some text: % t=text(.1,.7,'This is a test','FontName','Arial','FontSize',fs) % % Draw some two-line text: % t=text(.1,.5,sprintf('This is a test \nThis is a test'),'FontName','Arial','FontSize',fs) % % Overlap two lines, need sprintf as it affects text placemnt % t=text(.27,.5,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs) % dy=.063 % This value depends on figure size, WTF? % t=text(.27,.5-dy,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs)
dy=.063; % This value depends on figure size, WTF? x=-.168; y=1.03; %t=text(x,y,sprintf('This is a test \n This is a test'),'FontName','Courier','FontSize',fs) %t=text(x,y-dy/2,sprintf('This is a test \n '),'FontName','Courier','FontSize',fs) %return
% t=text(x,y,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-dy/2,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-dy,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-1.5dy,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-2dy,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-2.5*dy,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs)
%char(32:1:126) %char(48:1:58) % 10 digits %char(65:1:90) % 26 caps xs=301; ys=301;
%char(C)
% Replace every \ (92) and _ (95) with space (32) C=C.(C~=92)+(C==92)32; C=C.(C~=95)+(C==95)32; C=C.(C~=91)+(C==91)32; C=C.(C~=123)+(C==123)32;
for i=1:ny str=[ char(C(i,:)) '\n']; %str=['ABCDEF\n']; t=text(x,y-dy*(i-1)/2,sprintf(str),'FontName','Courier','FontSize',fs,'FontWeight','Bold'); end
%pos=get(f,'Position') %set(f,'Position',[pos(1) 150 160 160]); F = getframe(gcf); [g, Map] = frame2im(F);
%print -dbmp fig.bmp %g=imread('fig.bmp'); gg=g(:,:,1)+g(:,:,2)+g(:,:,3);
spy(gg<150)
b=gg(1:xs,1:ys); b=b<150; spy(b)
%whos a b; %return
subplot(2,2,1) spy(a) subplot(2,2,2) spy(b) pos=get(f,'Position'); %set(f,'Position',[1200 pos(2) pos(3) pos(4)])
norm(a-b); val=-sum(sum(a.b))-sum(sum((1-a).(1-b)));
if val<best BESTC=C; best=val; bb=b; disp(['New improved image, value is: ' num2str(val) ' at itaration ' num2str(k)]); else C=OC;
end [row,col]=size(C); %char(32:1:126) %C(randi(row),randi(col))=59+randi(31,1,1) OC=C; C(randi(row),randi(col))=31+randi(125-32,1,1);
end %END BIG LOOP
%disp(char(BESTC)) best subplot(2,2,3) spy(bb) subplot(2,2,4) spy((1-a).*(1-bb)) spy(b-a)
str=' ' for m=1:size(a,1) for n=1:size(a,2) if a(m,n)==1 str(1,n)='1'; else str(1,n)='0'; end end %disp(str); end
save BESTC BESTC
Assuming you have a half-space along with a half-line feed gives a slightly better rendering IMHO.
close all nx=21 ny=27
%nx=3 % For testing %ny=3
C=64+randi(26,6,6)
C=59+randi(31,6,6)
%char(32:1:126) C=31+randi(126-32,ny,nx)
C=zeros(ny,nx)+32 best=99999
h=imread('rabbit.jpg'); hh=h(:,:,1)+h(:,:,2)+h(:,:,3); %whos h hh spy(hh>225) spy(hh(250:350,100:200)>225) spy(hh(150:450,100:400)>225) a=hh(150:450,100:400)>225;
for k=1:4000 %for k=1:30 % k=1
%close all
subplot(2,1,1);subplot(1,1,1) f=figure(1); pos=get(f,'Position'); %set(f,'Position',[1200 pos(2) pos(3) pos(4)])
axis off axis([0 1 0 1]); fs=18; % Draw some text: % t=text(.1,.7,'This is a test','FontName','Arial','FontSize',fs) % % Draw some two-line text: % t=text(.1,.5,sprintf('This is a test \nThis is a test'),'FontName','Arial','FontSize',fs) % % Overlap two lines, need sprintf as it affects text placemnt % t=text(.27,.5,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs) % dy=.063 % This value depends on figure size, WTF? % t=text(.27,.5-dy,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs)
dy=.063; % This value depends on figure size, WTF? dx=0.0145; x=-.168; y=1.03; %t=text(x,y,sprintf('This is a test \n This is a test'),'FontName','Courier','FontSize',fs) %t=text(x,y-dy/2,sprintf('This is a test \n '),'FontName','Courier','FontSize',fs) %return
% t=text(x,y,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-dy/2,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-dy,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-1.5dy,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-2dy,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs) % t=text(x,y-2.5*dy,sprintf('ABCDE\n'),'FontName','Arial','FontSize',fs)
%char(32:1:126) %char(48:1:58) % 10 digits %char(65:1:90) % 26 caps xs=301; ys=301;
%char(C)
% Replace every \ (92) and _ (95) with space (32) C=C.(C~=92)+(C==92)32; C=C.(C~=95)+(C==95)32; C=C.(C~=91)+(C==91)32; C=C.(C~=123)+(C==123)32;
for i=1:ny str=[ char(C(i,:)) '\n']; %str=['ABCDEF\n']; %str=['XXXXXX\n']; if mod(i,2)==1 % Odd case t=text(x,y-dy(i-1)/2,sprintf(str),'FontName','Courier','FontSize',fs,'FontWeight','Bold'); else t=text(x+dx,y-dy(i-1)/2,sprintf(str),'FontName','Courier','FontSize',fs,'FontWeight','Bold'); end
end
%pos=get(f,'Position') %set(f,'Position',[pos(1) 150 160 160]); F = getframe(gcf); [g, Map] = frame2im(F);
%print -dbmp fig.bmp %g=imread('fig.bmp'); gg=g(:,:,1)+g(:,:,2)+g(:,:,3);
spy(gg<150)
b=gg(1:xs,1:ys); b=b<150; spy(b)
%whos a b; %return
subplot(2,2,1) spy(a) subplot(2,2,2) spy(b) pos=get(f,'Position'); %set(f,'Position',[1200 pos(2) pos(3) pos(4)])
norm(a-b); val=-sum(sum(a.b))-sum(sum((1-a).(1-b)));
if val<best BESTC=C; best=val; bb=b; disp(['New improved image, value is: ' num2str(val) ' at iteration ' num2str(k)]); else C=OC;
end [row,col]=size(C); %char(32:1:126) %C(randi(row),randi(col))=59+randi(31,1,1) OC=C; C(randi(row),randi(col))=31+randi(125-32,1,1);
end %END BIG LOOP
%disp(char(BESTC)) best subplot(2,2,3) spy(bb) subplot(2,2,4) spy((1-a).*(1-bb)) spy(b-a)
str=' ' for m=1:size(a,1) for n=1:size(a,2) if a(m,n)==1 str(1,n)='1'; else str(1,n)='0'; end end %disp(str); end
save BESTC BESTC
I had a bit of nostalgia recently and started a quest to find pre-ascii typewriter art using half carriage feeds to partially overlap lines.
I did find some folks do overstrike art, re-running the full line with text overstrikes.
I have not yet dug into your jp2a utility, but I wonder if you think this could be a possible (easy) modification or option? I am not super familiar with the area so this may already exist. Overstrike, half returns, etc.
A half return would complicate things because we can't display easily so you have to have a display app or write the resulting output to PDF maybe?
I am a MATLAB junkie, so I copied in an example of what I am talking about. I tested it in octave online as well and it seems to render for me with a half step. https://octave-online.net/
Thanks for your utility!
Ed Gatzke
BTW, I tried to email csl@csl.name and it bounced. ???
subplot(2,1,1);subplot(1,1,1) f=figure(1) axis off axis([0 1 0 1]) fs=14 % Draw some text: t=text(.1,.7,'This is a test','FontName','Arial','FontSize',fs)
% Draw some two-line text: t=text(.1,.5,sprintf('This is a test \nThis is a test'),'FontName','Arial','FontSize',fs)
% Overlap two lines, need sprintf as it affects text placemnt t=text(.27,.5,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs) dy=.063 % This value depends on figure size, WTF? t=text(.27,.5-dy,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs)
t=text(.1,.2,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs) t=text(.1,.2-dy/2,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs) t=text(.1,.2-dy,sprintf('This is a test \n '),'FontName','Arial','FontSize',fs)