Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!uwm.edu!ogicse!plains!bakke From: bakke@plains.NoDak.edu (Jeffrey P. Bakke) Newsgroups: comp.graphics Subject: Image Scaling (Replies) Message-ID: <6364@plains.NoDak.edu> Date: 19 Oct 90 16:18:32 GMT Organization: North Dakota State University, Fargo Lines: 319 I had a request to post all the replies and information that I received regarding Image Scaling (shrinking an image). Here it is. Thanks for all of the replies and help. From ted@aps1.spa.umn.edu Wed Oct 10 13:33:54 1990 Take a look at the pbmplus package, available via ftp (see Freq. asked question posting for how to get it). It includes code for scaling color images (ppmscale). The code should be easy to adapt to your purpose. From sloan@cs.washington.edu Wed Oct 10 22:19:56 1990 Subsampling an image (what you asked about) is really quite easy - once you build the right tools. Supersampling (blowing up the image) is a bit harder - but you didn't ask about that. The first try is to simply subsample. Given a high resolution image with dimensions NxN, that you want to resample at MxM, with M < N, all you have to do is: for(x=0;x N/2xN/2. If you want to make the image much smaller than half the linear size of the original, you need to average over larger neighborhoods (or, filter several times). Now, my preference is to build a program which performs the 3x3 convolution, and a separate subsampling program. so, to "properly" downsize an image, you do: cat NxNImage | Convolve | SubSample >MxMImage But, you can also write one program which convolves and samples simultaneously. It looks something like: for(x=0;x #include "pxm.h" #define DEBUG(x) /* x */ #define TRACE(x) /* x */ long sx = 0; /* source x size */ long sy = 0; /* source y size */ long tx = 0; /* target x size */ long ty = 0; /* target y size */ int verbose = 0; /* verbose flag */ banner() { printf("%s v%s -- %s\n", _Program, _Version, _Copyright); } usage() { fprintf(stderr, "usage: %s [-v] [-x newsize] [-y newsize] inpxm outpxm\n", _Program); exit(1); } progress(a, b) long a, b; { printf("%3ld%%\r", ((a * 100) / b)); } main(argc, argv) int argc; char *argv[]; { register PX_DEF *ipx, *opx; FILE *f; register int c; register char *p; extern int optind; extern char *optarg; int w, h; while((c = getopt(argc, argv, "x:y:vV")) != EOF) { switch(c) { case 'x': tx = atoi(optarg); break; case 'y': ty = atoi(optarg); break; case 'v': verbose = !verbose; break; case 'V': banner(); exit(0); case '?': default: usage(); } } if((argc - optind) < 2) { usage(); } else { setbuf(stdout, NULL); TRACE(fprintf(stderr, "rescale: opening pxms\n")); ipx = px_ropen(argv[optind++]); sx = (long) ipx->px_width; sy = (long) ipx->px_height; if(tx == 0) { tx = sx; } if(ty == 0) { ty = sy; } if(verbose) { printf("inpxm (%ldx%ld) --> outpxm (%ldx%ld)\n", sx, sy, tx, ty); } opx = px_wopen(argv[optind++], ipx->px_type, (int) tx, (int) ty, ipx->px_depth, ipx->px_map); TRACE(fprintf(stderr, "rescale: scaling pxms\n")); rescale(ipx, opx); TRACE(fprintf(stderr, "rescale: closing pxms\n")); px_close(ipx); opx->px_map = NULL; /* prevent double free() */ px_close(opx); } exit(0); } #define XSCALE(x) (int)((((long)(x)) * sx) / tx) #define YSCALE(y) (int)((((long)(y)) * sy) / ty) rescale(ipx, opx) PX_DEF *ipx, *opx; { int y0, yy, y; register int x, xx, n, i; register PX_BYTE *ibuf, *obuf; ibuf = px_rowalloc(ipx->px_width, ipx->px_psize); obuf = px_rowalloc(opx->px_width, opx->px_psize); n = opx->px_psize; y0 = -1; for(y = 0; y < ty; ++y) { if(verbose) { progress((long) y, ty); } yy = YSCALE(y); while(yy > y0) { TRACE(fprintf(stderr, "rescale: y=%d yy=%d y0=%d\n", y, yy, y0)); px_rrow(ipx, ibuf); ++y0; } if(n == 1) { for(x = 0; x < tx; ++x) { xx = XSCALE(x); obuf[x] = ibuf[xx]; } } else { for(x = 0; x < tx; ++x) { xx = XSCALE(x); for(i = 0; i < n; ++i) { obuf[(x * n) + i] = ibuf[(xx * n) + i]; } } } px_wrow(opx, obuf); } free(ibuf); free(obuf); } From the NET: ------------- Watson, Andrew B. "Ideal shrinking and expansion of discrete sequences" NASA Technical Memorandum #88202 The best way to get ahold of this is simply to write the author and ask for a copy: A.B. Watson -> beau@gauss.arc.nasa.gov *OR* Andrew B. Watson NASA Ames Research Center Mail Stop 262-2 Moffett Field CA 94035-1000 Thanks again for all replies and information. -- Jeffrey P. Bakke Internet: bakke@plains.NoDak.edu UUCP : ...!uunet!plains!bakke BITNET : bakke@plains.bitnet