

Picture Twister is a graphic program that performs 2D geometric transformation and image distortion. By specifying the degree and direction of distortion, special visual effects will be seen. This can be done by allowing user to draw a line segment directly on the picture, while the starting and ending points specify the direction, and the length of the line specifies the degree of distortion. Users can perform morphing multiple times until the satisfied picture comes up. User can save it as a graphic file for future reference.
Several extra functionalites can be added to this program to create additional visual effects. For example, if we allow computer to generate the distortion parameters continuously, we can create animation from static picture.
The algorithm involves double interpolation and floating point arithmetic. Picture Twister will use protected mode and allow user to save/load graphic files.
Features:
title page
picture before
distortion
picture after distortion
direction page
The MainLoop is what brings the program together. It contains a event loop which will call the right functionality according to a jump table. For example, when you press F1, it will ask for a bitmap file name, and load the picture onto the screen.
Flow of the Main:
The event loop will be implemented using a Jump Table.
It has seven parts to it: EventLoad, EventSave, EventReset, EventBlur,
EventWarp, EventDirection, and EventExit. The jump table will choose
the right function to jump to once user has select the choice from the
menu bar(Load, Save, Reset, Blur, Warp,Exit). The jump table will have
the following format:
EventJumpTable[BX]
EventJumpTable db EventLoad
db EventSave
:
:
db EventExit
EventLoad: do something ...
EventSave: do something ...
EventReset: do something else ..
EventExit: do something else ..
The mouse handling is used by the warping algorithm to draw lines. It outputs the current X and Y coordinates of the mouse position, and a ESC key status (-1 = ESC press). Mouse handling in protected mode high graphic resolution is done differently than real mode or text mode. You cannot just show the mouse cursor on the screen by calling 01h, 33h ( the mouse interrupt for showing the mouse) since high graphic resolution cannot recognize the interrupt call.
Luckily, we found a way around that. First, call 03h, 33h to get the current position of the mouse. Second, store the pixels that the mouse is going to cover into the memory. Third, draw the mouse onto the screen. Fourth, once the mouse moves away, recover the pixels that the mouse covered.
As stated before, the mouse handling is only used by the warping algorithm to draw line between two points so that the warping can be performed along the direction of the line. Click the mouse once to select the starting point of the line, and click the mouse again to choose the ending point. Since the warping algorithm is a very fast algorithm, we need to put a MouseDelayTime to slow it down a little so that it can recognize the mouse click.
2D Morphing Algorithm
- by Chun-wei Lam, Shane Thomas
There are tons of ways to perform image morphing. One of the algorithms that is widely used is called Field Morphing introduced by Thaddeus Beier[1]. Other algorithms include triangle to triangle correspondence, line to line correspondence and based warping..etc.
Fortunately, we found an image warping java applet that we can refer to. The author of the applet, Alex Rosen, disclosed the source code of the program and allowed everybody to access it from his website: http://www.tiac.net/users/axlrosen/.
Floating point arthimetics is used in order to preserve the precision of the interpolation factor. After the interpolation, we round off the result and call _WritePixelVESA, _ReadPixelVESA to perform the actual drawing. Due to the rounding error, the interpolation result is not very linear. But overall, the performance is acceptable.
Handling of the graphics and memory will involve four different functions. These four functions are: load the graphics, save the graphics, resizes the graphics, draws the graphics with resize. For a normal picture and the background we will use the video buffer to transfer files to the page. We will use two buffers when we warp the picture passing the warped picture from a warp buffer to the video buffer then to the screen.
Loading the bitmap file can be done by calling Pete's library (_LoadBMP, RefreshVideoBuffer). Saving the bitmap file is a bit tricky to do. It is essentially the reverse of the loading bitmap with the need of defining the header file first. The purpose the the resize picture is to miniaturize the 640*480 picture to 320*240 to fit it into our working area. This can be done by taking one pixel out of every two pixels in the 640*480 picture.
Animation on the title page
- by Chun-wei Jethro Lam
This is an example of extra functionality mentioned in the introduction. Instead of taking parameters from users, we predefined a set of points and pass them into the WarpRegion subroutine as parameters. The subroutine will perform warping at these points continuously and thus create an animation effect.
| .BSS |
| For the jump table |
| EventJumpTable --- a jump table used to check events |
| For the mouse |
| Following are the X and
Y coordinate of where you are going to draw the mouse
PosX PosY CursorX1 CursorX2 CursorX3 CursorY1 CursorY2 CursorY3 Following are the variables
to store the color of pixels which the mouse will cover
ButtonStat --- button status
of the mouse
|
| For Blur |
| Following are the variables
used in blur to blur the picture
PixelBlue PixelRed PixelGreen |
| For memory allocation |
WarpBlock --- WarpBlock |
| For the warping algorithm |
| counterA resw 1 - counter for loops in FPU
mode
counterB resw 1 Distance resd 1 - distance between the start and end point SE_X resw 1 - (X,Y) coordinates
of the rectangle
ToPtX resw 1 - (X,Y) coordinates of the start
and end point
X1 resd 1 - (X,Y) of the quadrilateral lines
DeltaX resd 1 - width of the rectangle
Xin resd 1 - increment of X
intXin resw 1 - integer value of Xin
inttoX resw 1 - integer value of ToPtX
Ftemp resw 1 - temp memory for FPU stack. use to load register value into FPU DeltaXin resd 1 - change in Xin
|
| .DATA |
| For TakeFilename |
| SavePrompt --- holds the string that prompts user to save
LoadPrompt --- holds the string that prompts user to load InputString --- holds the string that user enters padding --- provide space for input filename |
| For ShowTitle |
| WarpLocusX --- locus of
the warping process
WarpLocusY |
| For the mouse |
| Following are the variables to restore the X and Y coordinates of the
pixels being covered by the mouse
OldX OldY OldCursorX1 OldCursorX2 OldCursorX3 OldCursorY1 OldCursorY2 OldCursorY3 MouseTimeDelay --- a delay added in to slow down the warping algorithm |
| Draw line using keyboard |
| CursorSpeed --- define the speed
of the cursor
DrawLineX1 --- X coordinate of the starting point for draw line DrawLineY1 --- Y coordinate of the starting point for draw line Blur_Y1 --- bluring variable Blur_X1 --- bluring varialbe |
| Graphic files used |
| Following are the bitmap files we used for the program
Title ---Title.bmp, our title page Workarea ---Workarea.bmp, our working area page Credit --- Credit.bmp, our credit page NoImage --- Noimage.bmp, another workarea page Direction --- Direct.bmp, our direction page |
| For Blur |
| screen_offset --- 2D arrays
used by blurring
weights --- 2D arrays used by blurring |
| CONSTANT |
| WarplocusOffsetX equ 320 - position on screen where warping takes place
WarplocusOffsetY equ 150 WarplocusDegree equ 12 - degree of the warping |
This is done in a similar fashion as MP4
EventDirection
calcDist
DrawLineWithKeyboard
FadeOutStyle1/FadeOutStyle2
DrawLine
List of subroutines that we used in our project:
Pete Johnson
All ECE291 TAs
Shaun Chan --- for lending us the zip drive