// ------------------------------------------------------------------------ // This program is complementary material for the book: // // Frank Nielsen // // Visual Computing: Geometry, Graphics, and Vision // // ISBN: 1-58450-427-7 // // Charles River Media, Inc. // // // All programs are available at http://www.charlesriver.com/visualcomputing/ // // You may use this program for ACADEMIC and PERSONAL purposes ONLY. // // // The use of this program in a commercial product requires EXPLICITLY // written permission from the author. The author is NOT responsible or // liable for damage or loss that may be caused by the use of this program. // // Copyright (c) 2005. Frank Nielsen. All rights reserved. // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ // File: errordiffusion.cpp // // Description: Halftoning and dithering (error diffusion of Floyd-Steinberg) // ------------------------------------------------------------------------ #include "stdafx.h" #include #include using namespace std; void SaveImagePPM(unsigned char * data, int w, int h, char * file); unsigned char * LoadImagePPM(char *ifile, int &w, int &h); char filenameinput[]="lena.ppm"; char filenamethreshold[]="binary-threshold.ppm"; char filenamerandomthreshold[]="binary-randomthreshold.ppm"; char filenameerrordiffusion[]="binary-diffusion.ppm"; char filenamedither[]="tone-dither.ppm"; int _tmain(int argc, _TCHAR* argv[]) { unsigned char * img, * imgd; int x,y,index; int w,h; cout<<"Visual Computing: Geometry, Graphics, and Vision (ISBN:1-58450-427-7)"<127) { imgd[index] =255; imgd[index+1]=255; imgd[index+2]=255; } else { imgd[index] =0; imgd[index+1]=0; imgd[index+2]=0; } } SaveImagePPM(imgd,w,h,filenamethreshold); srand(2004); // Constant threshold for(x=0;x (rand()%127)) { imgd[index] =255; imgd[index+1]=255; imgd[index+2]=255; } else { imgd[index] =0; imgd[index+1]=0; imgd[index+2]=0; } } SaveImagePPM(imgd,w,h,filenamerandomthreshold); // Error diffusion unsigned char error; float delta; for(x=0;x (rand()%127)) { imgd[index] =255; imgd[index+1]=255; imgd[index+2]=255; error=255-img[index]; } else { imgd[index] =0; imgd[index+1]=0; imgd[index+2]=0; error=-img[index]; } if ((y0)) { // Now diffuse the error delta=img[index+1]+error*7.0/16.0; if (delta<0) img[index+1]=0; if (delta>255) img[index+1]=255; else img[index+1]=(unsigned char)delta; index=3*(x-1+(y+1)+w); delta=img[index]+error*3.0/16.0; if (delta<0) img[index]=0; if (delta>255) img[index]=255; else img[index]=(unsigned char)delta; index=3*(x+(y+1)+w); delta=img[index]+error*5.0/16.0; if (delta<0) img[index]=0; if (delta>255) img[index]=255; else img[index]=(unsigned char)delta; } } SaveImagePPM(imgd,w,h,filenameerrordiffusion); unsigned char dithercell[2][2]={{48,144}, {192, 96}}; // Dithering // for(x=0;x dithercell[y%2][x%2]) { imgd[index] =255; imgd[index+1]=255; imgd[index+2]=255; } else { imgd[index] =0; imgd[index+1]=0; imgd[index+2]=0; } } SaveImagePPM(imgd,w,h,filenamedither); delete [] img; char line[256]; cout<<"Press Return key"<> w >> h; IN >> maxc; IN.get(dummy1); img=new unsigned char[3*w*h]; IN.read((char *)img, 3*w*h); IN.close(); return img; }