Overview
PerspectiveTransformEffectLib applies a 3D perspective transformation to an image by manipulating its four corner points, wrapping the FireMonkey TPerspectiveTransformEffect component. By moving the corners independently, you can create perspective tilts, skewing, and 3D-like distortions — useful for placing images on angled surfaces or creating dynamic visual effects.
| Property | Details |
|---|---|
| Library | PerspectiveTransformEffectLib |
| Prefix | persp_ |
| Wraps | TPerspectiveTransformEffect |
| Functions | 26 |
| Type | Visual effect (geometric transform) |
| Category | Count | Description |
|---|---|---|
| Creation / Destruction | 2 | Create and free effect |
| Corner Points | 16 | Get/set X,Y for 4 corners |
| Effect Control | 4 | Enabled and trigger get/set |
| Error Handling | 4 | Error codes and messages |
Coordinate System
The effect defines the image shape by four corner points in pixel coordinates. For a 200×150 image, the default (undistorted) layout is:
(0,0) TopLeft ──────────── TopRight (200,0) │ │ │ I M A G E │ │ │ (0,150) BottomLeft ──────── BottomRight (200,150)
| Corner | Default X | Default Y | Functions |
|---|---|---|---|
| Top-Left | 0 | 0 | persp_topleftx / persp_toplefty |
| Top-Right | imgW | 0 | persp_toprightx / persp_toprighty |
| Bottom-Right | imgW | imgH | persp_bottomrightx / persp_bottomrighty |
| Bottom-Left | 0 | imgH | persp_bottomleftx / persp_bottomlefty |
Cross-Platform Support
| Platform | Support |
|---|---|
| Windows | ✅ Full support |
| Linux | ✅ Full support |
| Android | ✅ Full support |
Creation & Destruction
persp#(parent#)
Creates a new perspective transform effect attached to the specified visual control.
| Parameter | Type | Description |
|---|---|---|
parent# | Pointer | Target visual control (e.g., image) |
| Returns | Pointer | Effect handle, or 0 on failure |
persp_free(effect#)
Destroys the effect and releases associated resources.
let imgW = 200 let imgH = 150 let persp# = persp#(img#) ' Always initialize all corners first! persp_topleftx#(persp#, 0) persp_toplefty#(persp#, 0) persp_toprightx#(persp#, imgW) persp_toprighty#(persp#, 0) persp_bottomrightx#(persp#, imgW) persp_bottomrighty#(persp#, imgH) persp_bottomleftx#(persp#, 0) persp_bottomlefty#(persp#, imgH)
Error Handling
| Function | Signature | Description |
|---|---|---|
persp_error() | persp_error@ | Returns last error code (0 = none) |
persp_errormsg$() | persp_errormsg$@ | Returns last error message |
persp_strerror$(code) | persp_strerror$@n | Converts error code to text |
persp_clearerror() | persp_clearerror@ | Clears the error state |
Corner Points
Each of the four corners has independent X and Y coordinates, measured in pixels relative to the image dimensions.
Top-Left Corner
| Function | Signature | Description |
|---|---|---|
persp_topleftx#(effect#, value) | persp_topleftx#@#n | Set top-left X (pixels) |
persp_topleftx(effect#) | persp_topleftx@# | Get top-left X |
persp_toplefty#(effect#, value) | persp_toplefty#@#n | Set top-left Y (pixels) |
persp_toplefty(effect#) | persp_toplefty@# | Get top-left Y |
Top-Right Corner
| Function | Signature | Description |
|---|---|---|
persp_toprightx#(effect#, value) | persp_toprightx#@#n | Set top-right X (pixels) |
persp_toprightx(effect#) | persp_toprightx@# | Get top-right X |
persp_toprighty#(effect#, value) | persp_toprighty#@#n | Set top-right Y (pixels) |
persp_toprighty(effect#) | persp_toprighty@# | Get top-right Y |
Bottom-Right Corner
| Function | Signature | Description |
|---|---|---|
persp_bottomrightx#(effect#, value) | persp_bottomrightx#@#n | Set bottom-right X (pixels) |
persp_bottomrightx(effect#) | persp_bottomrightx@# | Get bottom-right X |
persp_bottomrighty#(effect#, value) | persp_bottomrighty#@#n | Set bottom-right Y (pixels) |
persp_bottomrighty(effect#) | persp_bottomrighty@# | Get bottom-right Y |
Bottom-Left Corner
| Function | Signature | Description |
|---|---|---|
persp_bottomleftx#(effect#, value) | persp_bottomleftx#@#n | Set bottom-left X (pixels) |
persp_bottomleftx(effect#) | persp_bottomleftx@# | Get bottom-left X |
persp_bottomlefty#(effect#, value) | persp_bottomlefty#@#n | Set bottom-left Y (pixels) |
persp_bottomlefty(effect#) | persp_bottomlefty@# | Get bottom-left Y |
Effect Control
| Function | Signature | Description |
|---|---|---|
persp_enabled#(effect#, value) | persp_enabled#@#n | Enable (1) or disable (0) |
persp_enabled(effect#) | persp_enabled@# | Gets enabled state |
persp_trigger#(effect#, trigger$) | persp_trigger#@#$ | Sets trigger string |
persp_trigger$(effect#) | persp_trigger$@# | Gets trigger string |
Complete Examples
Example 1: Basic Perspective Tilt
let frm# = Pointer#(0) let img# = Pointer#(0) let persp# = Pointer#(0) let imgW = 200 let imgH = 150 frm# = form#("Perspective Demo", 400, 350) img# = image#(frm#) image_bounds#(img#, 100, 50, imgW, imgH) image_load#(img#, "https://picsum.photos/200/150") persp# = persp#(img#) ' Initialize to full image size persp_topleftx#(persp#, 0) persp_toplefty#(persp#, 0) persp_toprightx#(persp#, imgW) persp_toprighty#(persp#, 0) persp_bottomrightx#(persp#, imgW) persp_bottomrighty#(persp#, imgH) persp_bottomleftx#(persp#, 0) persp_bottomlefty#(persp#, imgH) ' Narrow at top — creates receding perspective persp_topleftx#(persp#, 20) persp_toprightx#(persp#, imgW - 20) form_show(frm#)
Example 2: Interactive Corner Control
let frm# = Pointer#(0) let img# = Pointer#(0) let persp# = Pointer#(0) let trkTLX# = Pointer#(0) let trkTRX# = Pointer#(0) let lblTLX# = Pointer#(0) let lblTRX# = Pointer#(0) let imgW = 200 let imgH = 150 frm# = form#("Perspective Control", 500, 450) img# = image#(frm#) image_bounds#(img#, 150, 30, imgW, imgH) image_load#(img#, "https://picsum.photos/200/150") persp# = persp#(img#) persp_topleftx#(persp#, 0) persp_toplefty#(persp#, 0) persp_toprightx#(persp#, imgW) persp_toprighty#(persp#, 0) persp_bottomrightx#(persp#, imgW) persp_bottomrighty#(persp#, imgH) persp_bottomleftx#(persp#, 0) persp_bottomlefty#(persp#, imgH) ' Top-Left X slider lblTLX# = label#(frm#, "Top-Left X: 0", 30, 200) trkTLX# = trackbar#(frm#) trackbar_bounds#(trkTLX#, 30, 225, 200, 25) trackbar_max#(trkTLX#, 50) trackbar_value#(trkTLX#, 0) trackbar_onchange#(trkTLX#, "OnTLX") ' Top-Right X slider lblTRX# = label#(frm#, "Top-Right X: 200", 260, 200) trkTRX# = trackbar#(frm#) trackbar_bounds#(trkTRX#, 260, 225, 200, 25) trackbar_max#(trkTRX#, 50) trackbar_value#(trkTRX#, 50) trackbar_onchange#(trkTRX#, "OnTRX") form_show(frm#) function OnTLX(sender#) local x let x = trackbar_value(trkTLX#) persp_topleftx#(persp#, x) label_text#(lblTLX#, "Top-Left X: " + str$(x)) endfunction function OnTRX(sender#) local x let x = 150 + trackbar_value(trkTRX#) persp_toprightx#(persp#, x) label_text#(lblTRX#, "Top-Right X: " + str$(x)) endfunction
Example 3: Preset Perspective Modes
let frm# = Pointer#(0) let img# = Pointer#(0) let persp# = Pointer#(0) let lblMode# = Pointer#(0) let imgW = 200 let imgH = 150 frm# = form#("Perspective Presets", 450, 400) img# = image#(frm#) image_bounds#(img#, 125, 30, imgW, imgH) image_load#(img#, "https://picsum.photos/200/150") persp# = persp#(img#) persp_topleftx#(persp#, 0) persp_toplefty#(persp#, 0) persp_toprightx#(persp#, imgW) persp_toprighty#(persp#, 0) persp_bottomrightx#(persp#, imgW) persp_bottomrighty#(persp#, imgH) persp_bottomleftx#(persp#, 0) persp_bottomlefty#(persp#, imgH) lblMode# = label#(frm#, "Mode: Normal", 175, 200) let btn1# = button#(frm#, "Normal") button_bounds#(btn1#, 30, 240, 80, 30) button_onclick#(btn1#, "ModeNormal") let btn2# = button#(frm#, "Tilt Top") button_bounds#(btn2#, 120, 240, 80, 30) button_onclick#(btn2#, "ModeTilt") let btn3# = button#(frm#, "Tilt Left") button_bounds#(btn3#, 210, 240, 80, 30) button_onclick#(btn3#, "ModeLeft") let btn4# = button#(frm#, "Skew") button_bounds#(btn4#, 300, 240, 80, 30) button_onclick#(btn4#, "ModeSkew") form_show(frm#) function ModeNormal(sender#) persp_topleftx#(persp#, 0) persp_toplefty#(persp#, 0) persp_toprightx#(persp#, imgW) persp_toprighty#(persp#, 0) persp_bottomrightx#(persp#, imgW) persp_bottomrighty#(persp#, imgH) persp_bottomleftx#(persp#, 0) persp_bottomlefty#(persp#, imgH) label_text#(lblMode#, "Mode: Normal") endfunction function ModeTilt(sender#) persp_topleftx#(persp#, 30) persp_toprightx#(persp#, imgW - 30) persp_bottomleftx#(persp#, 0) persp_bottomrightx#(persp#, imgW) label_text#(lblMode#, "Mode: Tilt Top") endfunction function ModeLeft(sender#) persp_toplefty#(persp#, 15) persp_bottomlefty#(persp#, imgH - 15) persp_toprighty#(persp#, 0) persp_bottomrighty#(persp#, imgH) label_text#(lblMode#, "Mode: Tilt Left") endfunction function ModeSkew(sender#) persp_topleftx#(persp#, 20) persp_toprighty#(persp#, 15) persp_bottomrightx#(persp#, imgW - 20) persp_bottomlefty#(persp#, imgH - 15) label_text#(lblMode#, "Mode: Skew") endfunction
Best Practices
| Practice | Why |
|---|---|
| Always initialize all 8 corner values | Default values are small and may make the image invisible |
| Use image dimensions for defaults | Set corners to (0,0), (W,0), (W,H), (0,H) first |
| Move corners inward for receding perspective | Narrowing the top creates "tilting away" illusion |
| Keep coordinates within image bounds | Extreme values may produce unexpected distortions |
| Store image dimensions in variables | Makes corner calculations cleaner and reusable |
Quick Reference
| Function | Signature | Description |
|---|---|---|
| CREATION & DESTRUCTION | ||
persp#(parent#) | persp#@# | Create effect |
persp_free(effect#) | persp_free@# | Destroy effect |
| TOP-LEFT CORNER | ||
persp_topleftx#(effect#, value) | persp_topleftx#@#n | Set top-left X |
persp_topleftx(effect#) | persp_topleftx@# | Get top-left X |
persp_toplefty#(effect#, value) | persp_toplefty#@#n | Set top-left Y |
persp_toplefty(effect#) | persp_toplefty@# | Get top-left Y |
| TOP-RIGHT CORNER | ||
persp_toprightx#(effect#, value) | persp_toprightx#@#n | Set top-right X |
persp_toprightx(effect#) | persp_toprightx@# | Get top-right X |
persp_toprighty#(effect#, value) | persp_toprighty#@#n | Set top-right Y |
persp_toprighty(effect#) | persp_toprighty@# | Get top-right Y |
| BOTTOM-RIGHT CORNER | ||
persp_bottomrightx#(effect#, value) | persp_bottomrightx#@#n | Set bottom-right X |
persp_bottomrightx(effect#) | persp_bottomrightx@# | Get bottom-right X |
persp_bottomrighty#(effect#, value) | persp_bottomrighty#@#n | Set bottom-right Y |
persp_bottomrighty(effect#) | persp_bottomrighty@# | Get bottom-right Y |
| BOTTOM-LEFT CORNER | ||
persp_bottomleftx#(effect#, value) | persp_bottomleftx#@#n | Set bottom-left X |
persp_bottomleftx(effect#) | persp_bottomleftx@# | Get bottom-left X |
persp_bottomlefty#(effect#, value) | persp_bottomlefty#@#n | Set bottom-left Y |
persp_bottomlefty(effect#) | persp_bottomlefty@# | Get bottom-left Y |
| EFFECT CONTROL | ||
persp_enabled#(effect#, value) | persp_enabled#@#n | Enable/disable |
persp_enabled(effect#) | persp_enabled@# | Get enabled state |
persp_trigger#(effect#, trigger$) | persp_trigger#@#$ | Set trigger |
persp_trigger$(effect#) | persp_trigger$@# | Get trigger |
| ERROR HANDLING | ||
persp_error() | persp_error@ | Last error code |
persp_errormsg$() | persp_errormsg$@ | Last error message |
persp_strerror$(code) | persp_strerror$@n | Code to text |
persp_clearerror() | persp_clearerror@ | Clear error state |
See Also
| Library | Description |
|---|---|
AffineTransformEffectLib | 2D transformations (scale, rotate, translate) |
WrapEffectLib | Wrap/warp distortion |
PinchEffectLib | Pinch/bulge distortion |
