Skip to content

Commit

Permalink
bugfixes in example logic and added dithering option
Browse files Browse the repository at this point in the history
  • Loading branch information
jbergen committed Mar 3, 2012
1 parent d0905d0 commit 8a206d1
Showing 1 changed file with 58 additions and 36 deletions.
94 changes: 58 additions & 36 deletions examples/Webcam/imageParse.pde
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
// printImage( brightnessArray, width, height, characterWidth, brightnessAdjustment, grid );

// printer settings
//small BIX STP-103 is 384 dots wide
// STP-350plus is 528 dots wide
int printWidth = 384; // in dots. should match the printer
int gridSpacing = 0; // 0 = no grid,
int brightnessAdjustment = 12; // darker < 0 < lighter
int gridSpacing = 24; // 0 = no grid, 23 = roughly square on the BIX
int brightnessAdjustment = -12; // darker < 0 < lighter

// 0 = 8 dot single density (square pixels)
// 1 = 8 dot double density (1x3 pixels | vertical)
// 32 = 24 dot single density
// 33 = 24 dot double density (1x1 square pixels)
int printMode = 33;

int ditherMode = 1; // 0 = Floyd Steinberg, 1 = Atkinson

void printImage(PImage f)
{
PImage img = makePrintable(f);
Expand All @@ -27,24 +31,12 @@ resizes if needed
PImage makePrintable(PImage img)
{
float r = (float) img.height / (float)img.width;

float verticalStretch = 1;
int widthInDots = ( printMode == 0 || printMode == 32) ? printWidth / 2 : printWidth;
switch( printMode )
{
case 0:
verticalStretch = 2;
break;
case 1:
verticalStretch = 1.0/3.0;
break;
case 32:
verticalStretch = 1.0/3.0;
break;
}
int actualHeight = (int) ( ( verticalStretch * ( widthInDots * r ) ) );
img.loadPixels();
img.resize( widthInDots,actualHeight);
float verticalStretch = ( printMode == 0 || printMode == 1 ) ? 1.0/3.0 : 1;
int scaledHeight = (int) ( ( verticalStretch * ( printWidth * r ) ) );

img.loadPixels();
img.resize( widthInDots , scaledHeight );
return img;
}

Expand All @@ -55,8 +47,6 @@ includes dithering logic
**********/
int[] parseImageToBytes(PImage img)
{

println("image: "+ img.width +":"+ img.height);
int numBytes = ceil(img.height/8.0 ) * img.width;
int[] bytes = new int[ numBytes ];
String[] binaryStringArray = new String[ numBytes ];
Expand All @@ -71,8 +61,7 @@ int[] parseImageToBytes(PImage img)
imgBrightness[i] = brightness( img.pixels[i] ) + brightnessAdjustment;
}

// DITHER from the brightness array
//http://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering


int grey = 126; //threshold grey

Expand All @@ -85,16 +74,45 @@ int[] parseImageToBytes(PImage img)

imgBrightness[ img.width * y + x ] = newPixel;
float quantError = oldPixel - newPixel;

if( (x % img.width) < img.width-1 ) imgBrightness[ img.width * y + (x+1) ] += ( 7.0/16.0 * quantError );
if( (x % img.width) > 0 && y < img.height-1 ) imgBrightness[ img.width * (y+1) + (x-1) ] += 3.0/16.0 * quantError;
if( y < img.height-1 ) imgBrightness[ img.width * (y+1) + (x) ] += 5.0/16.0 * quantError;
if( (x % img.width) < (img.width - 1) && y < (img.height - 1) ) imgBrightness[ img.width * (y+1) + (x+1) ] += 1.0/16.0 * quantError;

if(ditherMode == 1)
{
//
// Atkinson
// http://verlagmartinkoch.at/software/dither/index.html
//
// * 1/8 1/8
// 1/8 1/8 1/8
// 1/8

if( (x % img.width) < img.width-1 ) imgBrightness[ img.width * y + (x+1) ] += ( 1.0/8.0 * quantError );
if( (x % img.width) < img.width-2 ) imgBrightness[ img.width * y + (x+2) ] += ( 1.0/8.0 * quantError );

if( (x % img.width) > 0 && y < img.height-1 ) imgBrightness[ img.width * (y+1) + (x-1) ] += 1.0/8.0 * quantError;
if( y < img.height-1 ) imgBrightness[ img.width * (y+1) + (x) ] += 1.0/8.0 * quantError;
if( (x % img.width) < (img.width - 1) && y < (img.height - 1) ) imgBrightness[ img.width * (y+1) + (x+1) ] += 1.0/8.0 * quantError;

if( y < img.height-2 ) imgBrightness[ img.width * (y+2) + (x) ] += 1.0/8.0 * quantError;
}
else
{
//
// Floyd Steinberg
// http://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering
//
// * 7/16
// 3/16 5/16 1/16

if( (x % img.width) < img.width-1 ) imgBrightness[ img.width * y + (x+1) ] += ( 7.0/16.0 * quantError );

if( (x % img.width) > 0 && y < img.height-1 ) imgBrightness[ img.width * (y+1) + (x-1) ] += 3.0/16.0 * quantError;
if( y < img.height-1 ) imgBrightness[ img.width * (y+1) + (x) ] += 5.0/16.0 * quantError;
if( (x % img.width) < (img.width - 1) && y < (img.height - 1) ) imgBrightness[ img.width * (y+1) + (x+1) ] += 1.0/16.0 * quantError;
}
//////
if(printMode == 0)
{
if(y == 15 || y == 16) println(x +":"+y +" - "+ ( (int) floor(y / 8.0)*img.width + (x % img.width) ) );
//if(y == 15 || y == 16) println(x +":"+y +" - "+ ( (int) floor(y / 8.0)*img.width + (x % img.width) ) );
binaryStringArray[ (int) floor(y / 8.0)*img.width + (x % img.width) ] += (newPixel == 0 ) ? "1" : "0";
}
else if(printMode == 1)
Expand All @@ -121,28 +139,31 @@ int[] parseImageToBytes(PImage img)
if( binaryStringArray[i].length() == 0 ) println(binaryStringArray[i]);
}

//should have a big binary string

for( int i = 0 ; i < bytes.length ; i++)
{
int space = (printMode == 0 || printMode == 32) ? floor(gridSpacing/2) : gridSpacing;
if(printMode == 32 || printMode == 33)
bytes[i] = ( gridSpacing != 0 && ( i % (3 * gridSpacing) == 0 || i % ( 3 * gridSpacing) == 1 || i % ( 3 * gridSpacing) == 2 ) ) ? 0 : unbinary( binaryStringArray[i] );
bytes[i] = ( space != 0 && ( i % (3 * space) == 0 || i % ( 3 * space) == 1 || i % ( 3 * space) == 2 ) ) ? 0 : unbinary( binaryStringArray[i] );
else
bytes[i] = ( gridSpacing != 0 && i % gridSpacing == 0 ) ? 0 : unbinary( binaryStringArray[i] );
bytes[i] = ( space != 0 && i % space == 0 ) ? 0 : unbinary( binaryStringArray[i] );

}

return bytes;
}


void printToThermal(int[] bytes )
{
int characterWidth = 8;


int characterWidth = 8; // set here. printer freaks out if this is much larger
int d = ( printMode == 32 || printMode == 33 ) ? 3 : 1;
int widthInDots = ( printMode == 0 || printMode == 32 ) ? printWidth / 2 : printWidth;

for( int i = 0 ; i < bytes.length ; i+= characterWidth * d )
{
if( i % ( printWidth * d ) == 0 && i != 0 ) printer.printStorage();
if( i % ( widthInDots * d ) == 0 && i != 0 ) printer.printStorage();

int[] customCharacterBytes = new int[characterWidth * d];
arrayCopy( bytes, i , customCharacterBytes , 0 , characterWidth * d);
Expand All @@ -152,3 +173,4 @@ void printToThermal(int[] bytes )
printer.printStorage();
}


0 comments on commit 8a206d1

Please sign in to comment.