Warp Dr. Bill!

Point to a place on the image and then hold down the mouse button to drag it to a new place. Then release the button.


wpe26E.jpg (4210 bytes)    public void run() { Initialize(); // need to keep a thread going to update status while warping // (this won't work from the ImageWarper thread for some reason) while( mStartup != null ) { try { Thread.sleep(500); } catch ( InterruptedException e ) {} if ( !mReady ) { // if warping, add a period on the end of the status message mStatus += "."; showStatus( mStatus ); } } } void Initialize() { mStatus = "Loading image..."; showStatus( mStatus ); mReady = false; mCanUndo = false; mRedo = false; mUndoButton.disable(); // get warp image & dimensions mImage = getImage( getCodeBase(), mImageName ); while ( (mWidth=mImage.getWidth(this)) = kHOffset && x <>= kVOffset && y = kVOffset + mHeight ) y = kVOffset + mHeight - 1; } else if ( dy == 0 ) { if ( x = kHOffset + mWidth ) x = kHOffset + mWidth - 1; } else { double slope = (double)dy / dx; if ( x <+ (int)(slope * (x-from.x)); } if ( x>= kHOffset + mWidth ) { x = kHOffset + mWidth - 1; y = from.y + (int)(slope * (x-from.x)); } if ( y <+ (int)((y-from.y) / slope); } if ( y>= kVOffset + mHeight ) { y = kVOffset + mHeight - 1; x = from.x + (int)((y-from.y) / slope); } } return new Point( x, y ); } } /* * ImageWarper is the class that does the actual warping. Give it two * pixels buffers - one with the original image, and one to hold the new * image. It calls DoneWithWarping to let you know when it's all done. */ class ImageWarper extends Thread { AlexWarp mAlexWarp; Point mFromPoint, mToPoint; int mFromPixels[], mToPixels[]; int mWidth, mHeight; // width & height of warp image ImageWarper( AlexWarp j, int fromPixels[], int toPixels[], int w, int h, Point fromPoint, Point toPoint ) { mAlexWarp = j; mFromPixels = fromPixels; mToPixels = toPixels; mFromPoint = fromPoint; mToPoint = toPoint; mWidth = w; mHeight = h; } // warp the pixels, then notify the applet public void run() { WarpPixels(); mAlexWarp.DoneWithWarping(); } // warp mFromPixels into mToPixels void WarpPixels() { int dx = mToPoint.x-mFromPoint.x, dy = mToPoint.y-mFromPoint.y, dist = (int)Math.sqrt(dx*dx+dy*dy)*2; Rectangle r = new Rectangle(); Point ne = new Point(0,0), nw = new Point(0,0), se = new Point(0,0), sw = new Point(0,0); // copy mFromPixels to mToPixels, so the non-warped parts will be identical System.arraycopy( mFromPixels, 0, mToPixels, 0, mWidth*mHeight ); if ( dist == 0 ) return; // warp northeast quadrant SetRect( r, mFromPoint.x - dist, mFromPoint.y - dist, mFromPoint.x, mFromPoint.y ); ClipRect( r, mWidth, mHeight ); SetPt( ne, r.x, r.y ); SetPt( nw, r.x+r.width, r.y ); SetPt( se, r.x, r.y+r.height ); SetPt( sw, mToPoint.x, mToPoint.y ); WarpRegion( r, nw, ne, sw, se ); // warp nortwest quadrant SetRect( r, mFromPoint.x, mFromPoint.y - dist, mFromPoint.x + dist, mFromPoint.y ); ClipRect( r, mWidth, mHeight ); SetPt( ne, r.x, r.y ); SetPt( nw, r.x+r.width, r.y ); SetPt( se, mToPoint.x, mToPoint.y ); SetPt( sw, r.x+r.width, r.y+r.height ); WarpRegion( r, nw, ne, sw, se ); // warp southeast quadrant SetRect( r, mFromPoint.x - dist, mFromPoint.y, mFromPoint.x, mFromPoint.y + dist ); ClipRect( r, mWidth, mHeight ); SetPt( ne, r.x, r.y ); SetPt( nw, mToPoint.x, mToPoint.y ); SetPt( se, r.x, r.y+r.height ); SetPt( sw, r.x+r.width, r.y+r.height ); WarpRegion( r, nw, ne, sw, se ); // warp southwest quadrant SetRect( r, mFromPoint.x, mFromPoint.y, mFromPoint.x + dist, mFromPoint.y + dist ); ClipRect( r, mWidth, mHeight ); SetPt( ne, mToPoint.x, mToPoint.y ); SetPt( nw, r.x+r.width, r.y ); SetPt( se, r.x, r.y+r.height ); SetPt( sw, r.x+r.width, r.y+r.height ); WarpRegion( r, nw, ne, sw, se ); } // warp a quadrilateral into a rectangle (double-secret magic code!) void WarpRegion( Rectangle fromRect, Point nw, Point ne, Point sw, Point se ) { int dx = fromRect.width, dy = fromRect.height; double invDX = 1.0/dx, invDY = 1.0/dy; for ( int a = 0; a = mWidth ) xin = mWidth - 1; if ( yin = mHeight ) yin = mHeight - 1; int pixelValue = mFromPixels[ (int)xin + (int)yin * mWidth ]; mToPixels[ toPixel ] = pixelValue; xin += dxin; yin += dyin; toPixel += mWidth; } } } void ClipRect( Rectangle r, int w, int h ) { if ( r.x = w ) r.width = w - r.x - 1; if ( r.y+r.height >= h ) r.height = h - r.y - 1; } // SetRect and SetPt are Mac OS functions. I wrote my own versions here // so I didn't have to rewrite too much of the code. void SetRect( Rectangle r, int left, int top, int right, int bottom ) { r.x = left; r.y = top; r.width = right-left; r.height = bottom-top; } void SetPt( Point pt, int x, int y ) { pt.x = x; pt.y = y; } }
    wpe26D.jpg (4990 bytes)


AlexWarp applet by Alex Rosen - http://www.tiac.net/users/axlrosen/