#!/usr/bin/pike /* * cropzoomer.pike * * Utility to zoom a little on scanned pages (req. RGB page) * * Author: Dario Rodriguez dario@softhome.net * The program is licensed under the terms of the MIT/X license. */ int bgthreshold=64; // from 0 to 255 int amplitude=15; // from 1 to 255 int darkenfactor=2; // from 1 to 255 int main(int argc, array(string) argv) { Image.Image in,out,inhsv,indistance; string infile,outfile; if(argc!=3 || argv[argc-1]=="--help") { write("Syntax: "+argv[0]+" infile.jpg outfile.png\n"); return(1); } write(argv[1]+" -> "+argv[2]+"\n"); write("* Generating intermediate representations..."); infile=argv[1]; outfile=argv[2]; in=Image.load(infile); inhsv=in->copy()->rgb_to_hsv(); indistance=in->copy()->distancesq(255,255,255); out=Image.Image(in.xsize(),in.ysize()); // Guess the most used bg color write("done.\n* Guessing most used bg hue..."); array(int) hues=allocate(256); int x,y; int h,n,selh,seln,j; int c; for(y=0;yseln) { seln=n; selh=h; } } write(""+selh); // Getting image statistics write(".\n* Getting image statistics..."); int d; array(int) ycoverage=allocate(in.ysize()); for(y=0;y=2) { array(int) last=allocate(yblock); for(pos=0;pos=2) { array(int) last=allocate(xblock); for(pos=0;posymax) ymax=ycoverage[y]; } int xmax=0,xmin=in.xsize(); for(x=0;xxmax) xmax=xcoverage[x]; } int xdiff=(xmax-xmin); int ydiff=(ymax-ymin); int xminthreshold=xmin+xdiff/50; int yminthreshold=ymin+ydiff/50; // look for first dip under yminthreshold int y0,y1,x0,x1; for(y=in.ysize()/4;y>0;y--) { if(ycoverage[y]=in.ysize())?(in.ysize()-1):y1; // look for first dip under xminthreshold for(x=in.xsize()/4;x>0;x--) { if(xcoverage[x]=in.xsize())?(in.xsize()-1):x1; // Crop write(".\n* Cropping from "+out.xsize()+"x"+out.ysize()+" rectangle ("+x0+","+y0+")-("+x1+","+y1+")..."); out=in->copy(x0,y0,x1,y1,255,255,255); // Write result write("done.\n* Writing result to disk..."); Stdio.write_file(outfile,Image.PNG.encode(out)); write("done.\n* Process finished.\n"); }