Create bitmap within TeX file

I created simple visualizer module for luaqrcode:

module(...,package.seeall)
qrcodelib = dofile("qrencode.lua")
local function black_box(w,h)
  return "\\vrule width "..w.." height "..h
end
local function white_box(w,h)
  return "\\hskip "..w
end
function generate_matrix2(s,w,h)
  local ok, tab_or_message = qrcodelib.qrcode(s)
  local buffer = {}
  local write_nl = function(text)
    table.insert(buffer,text)
  end
  if not ok then
    print(tab_or_message)
  else
    write_nl("\\bgroup")
    --write_nl("\\vbox\\bgroup%")
    write_nl("\\baselineskip="..h)
    local x = #tab_or_message[1]
    local y = #tab_or_message
    for i = 1, x, 1 do
      local boxes = {}
      for n = 1, y, 1 do
        local p = tab_or_message[n][i] > 0  and black_box(w,h) or white_box(w,h)
        table.insert(boxes,p)
      end
      write_nl("\\hbox{"..table.concat(boxes).."}")
    end
    write_nl("\\egroup")
  end
  return table.concat(buffer,"")
end

And simple LaTeX interface and sample document:

\documentclass{article}
\usepackage{luacode}
\luaexec{qrcode = require("sample")}
\newcommand\qrcode[1]{%
  \vbox{
  \directlua{%
    tex.print(qrcode.generate_matrix2("\luatexluaescapestring{#1}","3pt","3pt"))
  }
  }
}
\begin{document}
Now generate some qrcodes:\\
\qrcode{Prilis zlutoucky kun upel dabelske ody}
\qrcode{Příliš žluťoučký kůň úpěl ďábelské ódy}
\qrcode{Helloworld}        
\end{document}

With this result: enter image description here


For this you need to create and add a PDF object (using \pdfobj I guess; see the pdftex manual) into the PDF which holds the (binary?) representation of the image and then reference this object where you like the image being shown. This is what \includegraphics does for PDF output.

Accroding to he PDF reference (31MB!), section 3.3.6 JBIG2Decode Filter the JBIG2 format was especially created for monochrome images like this. The best thing here is that it object stream can be given in ASCII, avoiding the need to handle binary material in TeX.

The following example is given there. I don't think there should be an issue adding this to a PDF using \pdfobj. You "only" need to produce the JBIG2 encoding of your image, which should be possible using Lua.

5 0 obj
<< /Type /XObject
/Subtype /Image
/Width 52
/Height 66
/ColorSpace /DeviceGray
/BitsPerComponent 1
/Length 224
/Filter [ /ASCIIHexDecode /JBIG2Decode ]
/DecodeParms [ null << /JBIG2Globals 6 0 R >> ]
>>
stream
000000013000010000001300000034000000420000000000
00000040000000000002062000010000001e000000340000
004200000000000000000200100000000231db51ce51ffac >
endstream
endobj
6 0 obj
<< /Length 126
/Filter /ASCIIHexDecode
>>
stream
0000000000010000000032000003fffdff02fefefe000000
01000000012ae225aea9a5a538b4d9999c5c8e56ef0f872
7f2b53d4e37ef795cc5506dffac >
endstream
endobj

I will try to create a LaTeX example file showing the principle.

So far I only figured out how to create the objects, but not how to display the image in the document.

\documentclass{article}

\pdfcompresslevel=0
\pdfobjcompresslevel=0

\begin{document}

\leavevmode\fbox{%

\pdfobj stream attr 
{
/Filter /ASCIIHexDecode
} {
0000000000010000000032000003fffdff02fefefe000000
01000000012ae225aea9a5a538b4d9999c5c8e56ef0f872
7f2b53d4e37ef795cc5506dffac
}%
%\pdfrefobj\pdflastobj
\pdfobj stream attr {
    /Type /XObject
/Subtype /Image
/Width 52
/Height 66
/ColorSpace /DeviceGray
/BitsPerComponent 1
%/Length 224
/Filter [ /ASCIIHexDecode /JBIG2Decode ]
/DecodeParms [ null << /JBIG2Globals \the\pdflastobj\space 0 R >> ]
} {
000000013000010000001300000034000000420000000000
00000040000000000002062000010000001e000000340000
004200000000000000000200100000000231db51ce51ffac
}%
\pdfrefobj\pdflastobj
}

\end{document}

I don't know if this is what you want:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\makebitmap}{O{4} m}
 {
  \topskip_make_bitmap:nn { #1 } { #2 }
 }

\cs_new_protected:Npn \topskip_make_bitmap:nn #1 #2
 {
  \tl_set:Nn \l__topskip_input_tl { #2 }
  \tl_remove_all:Nn \l__topskip_input_tl { ~ }
  \int_zero:N \l__topskip_cycle_int
  \tl_clear:N \l__topskip_bitmap_tl
  \tl_map_inline:Nn \l__topskip_input_tl
   {
    \int_incr:N \l__topskip_cycle_int
    \tl_put_right:Nx \l__topskip_bitmap_tl
     {
      \str_case:nnn { ##1 }
       {
        { 0 } { \topskip_zero: }
        { 1 } { \topskip_one:  }
       }
       { \topskip_error: }
      \int_compare:nTF { \l__topskip_cycle_int = #1 } { \cr } { & }
     }
    \int_compare:nT { \l__topskip_cycle_int = #1 } { \int_zero:N \l__topskip_cycle_int }
   }
  \vbox
   {
    \offinterlineskip
    \halign{&##\cr\l__topskip_bitmap_tl\crcr}}
 }
\cs_new_protected:Npn \topskip_zero:
 { \vrule height 3pt width 0pt\kern 3pt }
\cs_new_protected:Npn \topskip_one:
 { \vrule height 3pt width 3pt depth 0pt }

\int_new:N \l__topskip_cycle_int
\seq_new:N \l__topskip_bitmap_seq
\tl_new:N \l__topskip_bitmap_tl

\ExplSyntaxOff
\begin{document}
\fbox{\makebitmap{0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0}}
\fbox{\makebitmap{1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1}}
\fbox{\makebitmap[16]{
  1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1
  0 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0
  1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1
  0 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0
}}
\end{document}

enter image description here