curious technology logo

PngMagic - a simple JavaScript based image maker, batch image processor, and possibly a replacement for Windows Gadgets that's actually efficient.

Version 0.27:   2-16-17 Fixed OBD2 bugs
Version 0.26: 10-30-16 Implemented WebSockets (use ws://)
Version 0.25:   6- 6-16 Http request queue fixes.
Version 0.24: 10-20-2015 Bugs added.  Bugs fixed.
Version 0.23: 10-12-2015 Added Media, Gps, Obd objects.
Version 0.22:  9-11-2015 Added Http object.
Version 0.21:  6-11-2014 Added search.
Version 0.20:  2-17-2014 Bugs in the Save As.

  For 9-patch information see Reference
  For fixing locked png transparency pallets use the FixPng script.

Download   If you like it, please consider donating on the home page.

PngMagic editor and graphics Double-click from the list to edit a script.  Any changes are automatically saved. Drag images to insert full path at current position.

Click Run to run them.

New (also in context menu) to save current script and clear text editor (Unsaved will be in Untitled.js)
Combo Inserts:  Select one, then right click and select "Insert Template" in the context menu to insert it at the current cursor position.
<Color>              Inserts a Gdi.Argb(...) after color is chosen. Clicking on the image before inserting can set the starting palette color.
<Filename>         Inserts a 'Full path\\filename' or folder after chosen.
 <Font>               Inserts a Gdi.Font( name, size, properties) after selecting OK on a font chooser.
<x, y, w, h>        Inserts last clicked position in image display.  Click for just x, y, or press hold drag release for x,y,w,h.
< x1, y1, x2, y2>  Same as above but inserts absolute position for x2, y2.

The rest are templates.
General Helper Functions Red = optional
value = Pm.Argb(Alpha, Red, Green, Blue)
Example: Pm.Clear( Gdi.Argb(255, 0, 0, 0) )
Pm.Beep( var )
Example: Pm.Beep( 0 )                                         // Default Windows beep
btn = Pm.Button( x, y, w, h )                                // Sets a button region for click.  calls OnCall('BUTTON', btn) if clicked
Pm.Color( 'Item' ) = Rgb                                         // Set colors of different editor components
Rgb = Pm.Color( 'item' )                                         // Items: Background, Text, Comment, Number, String, Function, Constant
Pm.Echo( var )                                                      // Displays text in output window
Example: Pm.Echo( 'var i is ' + i )                           // Display the value of i
Pm.AnyScriptName( param1, param2... )                        // Call a script from the Scripts folder.  If params are given, it will run OnCall() in the script
Pm.PlaySound( File )                                            // Play a wav file. Same folder as exe or give full path
Example: Pm.PlaySound( 'C:\\Windows\\Media\\Tada.wav' )
Pm.Halt( )
Example: Pm.Halt()                                             // Stop script/close window
Pm.Show = true / false                                       // Show / hide main window
Pm.SetTimer( time, [Script] )
Example: Pm.SetTimer( 1000 )                           // Call OnTimer() every 1000ms
Pm.Smoothing = 'Option'                                    // None or Low, High or AntiAlias, 8x8
smoothing = Pm.Smoothing
Pm.Window( 'Name' )                                         // Creates new window.  All drawing for script will continue there instead of default window.
Pm.CloseWindow( 'Name' )                                 // Close the named window.  Can be used for external windows as well.
Pm.FindWindow( 'Name' )                                   // Finds a window, returns true/false.
Pm.CpuUsage                                                  // CPU usage in %
Pm.Memory                                                     // Memory free in %
Pm.NetTraffic( 'TX' | 'RX' )                                   // Network traffic in %
Pm.Volume = percent                                      // Set / get system volume
Pm.Mute = true | false                                     // Set / get system audio mute
File Operations
string = Pm.ReadFile( filename)                       // Read a file into string
Pm.DeleteFile( name )                                       // delete a file
Pm.DiskSpace( 'C:', ['size' 'free'] )                       // Returns free space % of disk.  Size in K or free in K 
Pm.FileExists( 'Filename' )
Example: If( Pm.FileExists( 'C:\\Windows\\win.ini' ) ) Pm.PlaySound( 'Ding.wav' )
Pm.Log( filename, string )                                    // Appends a text line to the file
Pm.Run( filename )                                            // Run an exe
Pm.Open( filename )                                          // Open a file with the associated exe
name = Pm.BrowseFile( 'defaultFile', 'Title' )            // Request a filename from user and return it in a variant
name = Pm.BrowseFolder( 'defaultFolder', 'Tiitle')    // Request a folder and return it
Drawing objects    Red = optional
Gdi.Pen( ARGB, Width, DashStyle|DashArray, DashOffset, DashCap// Styles: Solid, Dash, Dot, DashDot, DashDotDot - Caps: Flat, Round, Triangle, Square, Arrow, SArrow, EArrow
Example: Gdi.Pen( 0xFF00FF00, 1.0)                              // Green, smallest size
 dashes = new Array(20, 10)                             // Long lines with half spaces
Gdi.Pen( Gdi.Argb(255, 255, 0, 0), dashes)       // Red lines using the dash array
Gdi.Brush( ARGB )
Gdi.GradientBrush( X1, Y1, X2, Y2, StartARGB, EndARGB, Angle ) //
Gdi.PathBrush( PointArray, CenterColor, ColorArray, CenterX, CenterY )            //
Gdi.TextureBrush( Filename, TileSize )                                // Note: Current pen will inherit gradient
Drawing Functions Red = optional
Gdi.Clear( ARGB )
Example: Gdi.Clear(0x00000000)                                        // Set background to black, transparent
Example: Gdi.Clear(0xFF000000)                                       // Set background to black, opaque
Gdi.Line( StartX, StartY, EndX, EndY )                               // Uses last pen, draw a line from start to end
Gdi.Arc( X, Y, Width, Height, StartAngle, SweepAngle )       // Uses last pen
Gdi.Bezier( X1, Y1, X2, Y2, X3, Y3, X4, Y4 )                        // Uses last pen
Gdi.Rectangle( X, Y, Width, Height )                                   // Uses last pen
Gdi.FillRectangle( X, Y, Width, Height )                              
// Uses last brush
Gdi.Ellipse( X, Y, Width, Height )                                       // Uses last pen
Gdi.FillEllipse( X, Y, Width, Height )                                  
// Uses last brush
Gdi.Pie( X, Y, Width, Height, StartAngle, SweepAngle )       // Uses last pen
Gdi.FillPie( X, Y, Width, Height, StartAngle, SweepAngle )  
// Uses last brush
Gdi.Polygon( PointArray, CornerRadius )                            // Use pen to draw polygon  (array[0] = x1, array[1] = y1, array[2] = x2, array[3] = y2.....)
Gdi.FillPolygon( PointArray, CornerRadius )                        // Use brush to draw filled polygon using array object, optionally with rounded corners
Gdi.Curve( PointArray, tension)                                          // Use pen to draw a curve
Gdi.ClosedCurve( PointArray, tension)                                // Use pen to draw a closed curve
Gdi.FillClosedCurve( PointArray, tension)                            // Use brush to draw a filled closed curve
Argb = Gdi.Pixel( X, Y)                                                      // Get value of pixel at XY
Gdi.Pixel(X, Y) = Argb                                                       // Set pixel at XY
Gdi.Font( 'Fontname', Size, 'Style' )                                   // Set font for text  Style: Regular, Bold, Italic, BoldItalic, Underline, Strikeout
Example: Gdi.Font( 'Digital dream', 12)                               // Set font to Digital dream, size 12, normal style
Gdi.Text( String, X, Y, Alignment, Angle|Points )                 // Draw text using current font and last brush. Alignment = 'Left' 'Center' 'Right'
Gdi.OutlineText( String, X, Y, Fill, Alignment, Angle|Points ) // Draw outlined text using current font using last pen (and last brush if Fill = true)
   Gdi.Brush( Gdi.Argb(255, 255, 20, 255) ) // Purple brush
   Gdi.Pen( Gdi.Argb(20, 0, 0, 255), 1)        // Blue pen 20 alpha, 1px
   Gdi.OutlineText( 'Hello', 10, 10, 8)           // Draw purple Hello with soft blue glow (Fill > 1) = pen stroke radius
Image Functions
FrameCount = Gdi.LoadImage( Filename, 'Decompile' | Frame )  // Load an image (jpg, png, bmp, gif, ...) Decompile decompiles a 9-patch png
Gdi.Copy( X, Y, Width, Height, 'Option')  // Copy a section as an Image. Option: FlipX, FlipY, FlipXY, Rotate90FlipX (90,180,270) (X,Y,XY)
Gdi.RotateImage( X, Y, Angle, Size ) // Draw the image, at XY, rotated at Angle, stretched to Size maintaining aspect
Gdi.DrawImage( X, Y, Width, Height ) // Draw the image (Width only = specify size w/correct aspect | Width + Height = stretch)
Gdi.DrawImage( X, Y, 'Play' )             // Play an animated gif (loop only)
value = Gdi.ImageWidth                   // get current image width/height
value = Gdi.ImageHeight

Example: Pm.Echo( 'Image size is ' + Gdi.ImageWidth + ' by ' + Gdi.ImageHeight )
bool = Gdi.IsCompiled                     // True if last loaded image is a compiled 9-patch (Will be false If .9 and not compiled, but 9-patch will be generated)
Gdi.Save( Filename, X, Y, Width, Height, 'Option') // Supports png, jpg, tiff, bmp (Option: 'Compile' a 9-patch png or 'Clone' last loaded 9-patch)
Example: Gdi.Save( 'TestImage.png')                   // Save the current image to the current directory uncropped
Gdi.SetPatch( xStart, xEnd, yStart, yEnd, PaddingTop, PaddingBottom, PaddingLeft, PaddingRight) // When saving, use 'Clone' option
This sets 9-patch data programmatically instead of drawn, but can only do 1 pair per X/Y.
value = Gdi.Width                                               // width and height of window
value = Gdi.Height
Gdi.Width = width                                               // set new width/height
Gdi.Height = height
Gdi.Download( 'http://url', [filename]) // Reads a file off internet.  Returns path/filename saved
Example:  name = Gdi.Download( '', 'google.html' )
Effects Uses full work area if no dimensions set
Gdi.Blur( Radius, ExpandEdge , Left, Top, Right, Bottom)                                     // Radius in pixels (0-255), ExpandEdge = true/false
Gdi.BrightnessContrast( Brightnes, Contrast, Left, Top, Right, Bottom)                   // Brightness +/-255, Contrast +/-100
Gdi.ColorBalance( CyanRed, MagentaGreen, YellowBlue, Left, Top, Right, Bottom) // Color Range +/-100, 0 = Unchanged
Gdi.HueSaturationLightness( Hue, Saturation, Lightness, Left, Top, Right, Bottom) // Hue +/-180, Saturation +/-100, Lightness +/-100
Gdi.Levels( Highlight, Midtone, Shadow, Left, Top, Right, Bottom)                         // Highlight 0-100 (100=Unchanged), Midtone +/-100 (0=Unchanged), Shadow 0-100 (0=Unchanged)
Gdi.Sharpen( Radius, Amount, Left, Top, Right, Bottom)                                      // Radius in pixels (0-255), Amount 0-100
Gdi.Tint( Hue, Amount, Left, Top, Right, Bottom)                                                 // Hue +/-180, Amount +/-100
Http Object
bool = Http.Connect( 'handle', 'https://server/path?params=values',  'GET/POST', body, headers)     // Connect to a server

bool = Http.Connect( 'event', 'ws://server/ws')     // Connect to a server websocket
// Example support code

function OnCall( msg, handle, data )
          case 'HTTPDATA':
              Pm.Echo( 'Data ' + data )  // Prints the data received
          case 'HTTPSTATUS':
              Pm.Echo( 'Connect failed: ' + data )  // Error
          case 'HTTPCLOSE':
              Pm.Echo( 'Connection closed' )
Http.Close()                                // Close any open connection
string = Http.IP                           // Returns IP of client connected to this server
string = Http.ParamCount            // Returns param count from GET or POST request
string = Http.Params(n, bool )     // n = 0 to ParamCount-1, bool = 0 for name, 1 for value
string = Http.Params( "name" )   // returns value for name
bool = Http.Server( port )             // Starts a server on the given port

// Example support code
function OnCall( msg, data, path )
          case 'HTTPREQ':
              Pm.Echo( 'Req ' + data + ' ' + path)  // Prints GET or POST and path of requested file
              Http.Send( "HTTP/1.1 404 Not Found\r\n\r\n" )
          case 'HTTPSENT':
              Pm.Echo( 'File sent: ' + data + ' ' + path)  // If an existing file in "http" folder was sent
Http.Send( data )                         // Send data to client
Http.SendFile( path )                   // Send a file to client
Media Object
Media.Duration                           // Duration of current file
Media.Pause                             // Variant for controlling pause
Media.Play( filename )               // Plays a media file (audio only )
Media.Position                          // Position of current file
Media.Volume                           // Variant for controlling volume (0-100)
Media.Rate                               // Variant for play speed
Media.Stop()                             // Stop the player
Gps Object  (uses XPort or Sensor automatically, or COM port )
Gps.Direction(latitude, longitude, angle) // direction to point from current
Gps.Distance(lat, lon)
Gps.Latitude( 'String | Degrees | Minutes')
Gps.Longitude('String | Degrees | Minutes')
Gps.Log = true | false
Gps.Open( port, baud )
Gps.SatDat('Number | SNR | Elevation |Azimuth', sat number)
Gps.Speed('Mph | KPH')  // default=knots
Registry variants
Reg.key= value                    // Save a value to registry as 'key'
value = Reg.key                   // Retrieve value from registry
COM port
Com.Open( Port, baud )        // Open a COM port
Com.Write( data )                 // Write data to port

// Example support code
function OnCall( msg, data )
          case 'COM':
              Pm.Echo( 'Received ' + data)  // Prints the data received


  The entire JavaScript language is available excluding any html based extensions.

  All variants are persistent.  As long as the program is running, all variants will remain the same the next time a script is run.  So when running a script multiple times, the pen, brush, image, variables, strings, arrays, and work area will be the same as where the last script left off.

 Init.js is always run at start.

Copyright © 2018 Curious Technology