I'm trying to get a python script to work such a way that it takes a QR code (a jpeg or a png) splits the jpeg into two images as shown here https://github.com/LessonStudio/VisualCryptography

I'm not sure if the code can be scanned. I know we can get the image back, but what about the information stored ?

Any help would be appreciated.


2 Answers 2


A typical problem with the images regenerated by visual cryptography is that they have low contrast: when using superposed transparency, the white in the original image tends to become grey (or more precisely, 50% dithering of black and white, which is even worse from a 2D-code scanner's perspective); and there might be some white that creep in the black areas due to misalignment. This will be tolerated by some scanners, but will mess others. Scanning will be more difficult that with the original.

The classical scheme in figure 2 there will I guess not work reliably if each block on the original QR-code is split in two rectangles, as shown in that figure.

What would work better is to subdivide each block of the QR-code into a finer matrix, e.g 8x8: each block of the QR-code is turned to either X=X or Y=Y, where white is actually transparent:

  • A black block in the QR-code is, with odds 50%, turned to X in the first transparency and Y in the second transparency, or Y in the first and X in the second; so that the superposition of the transparencies will be essentially black.
  • A white block in the QR-code is, with odds 50%, turned to X in both transparencies, or Y in both transparencies; so that the superposition of the transparencies will be essentially grey (50% dithering of black and transparent).

No information can be extracted from a single transparency.

It might help to encode specially the blocks that convey only structure: Finder Pattern, Separator, Quiet Zone, Timing Pattern (if any), Alignment Pattern (if any). For these I suggest, in order to help determining orientation and putting the transparencies with the same side up:

  • A black block in the QR-code is represented as black in both transparencies.
  • A white block in the QR-code is represented as X or Y in both transparencies, according to $(h+\lfloor v/2\rfloor)\bmod 2$ where $h$ and $v$ are the block's coordinate as integers.

The above does not solve determining from which side the transparencies shall be scanned: not all scanners accept mirror images. But it would not be a good idea to solve this by replacing one transparency by a white sheet, as it could tend to worsen alignment problems: different materials react differently to humidity and aging. This side up probably will do (and be the simplest for orientation).

Choice of the appropriate block subdivision is a compromise: too coarse, and the scanner might consider the pixels of the block as the grid of the 2D barcode; too fine, and alignment of transparencies will become infeasible.

If one used polarizing filters with orientation of X and Y different by 90°, there would be no need for subdivision of QR-code blocks into smaller pixels, truer white (assuming a non-polarized light source behind the aligned transparencies), and no dithering for grey, thus easier reading. However, I know no automated way to prepare the transparencies; closest to a workable idea is to start from transparent polarized squares the size of a QR-code block, and glue them in the appropriate orientation on some grid.


Why use visual cryptography to split the QR code, and not secret-share the original data, and generate a QR code for each share instead? That way, you can scan the shares, and by combining them reconstruct the original secret.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.