MainExamplesDocumentationRegistration

 Info What is ShotGraph Why use ShotGraph Download How to register FAQ

 Making images Common principles Palettes OLE support ShotGraph on 64-bit Windows Creating animations Trick: anti-aliased fonts

# ShotGraph FAQ

Part 1  Part 2

To increase usability, this FAQ is divided on two parts now:
* The first part (this page) contains the questions "How to do something using ShotGraph?"
* The second part covers the questions about problems with installation/running/broken images/script debugging
##### How can I tell animated Gif from static one?
The GetFileDimensions method allows you to get only image type and dimensions. To retrieve number of frames in the animated Gif, use the ReadImage method. It contains the FramesCount output optional parameter and you should check value returned in this parameter. If this value greater 1 and image type is Gif then image is animated. The ReadImage works only if primary imagespace is created, therefore, you need to create some small one (CreateImage).
 This example demonstrates retrieving amount of frames from the image. Set g = CreateObject("shotgraph.image") filename = "c:\animated.gif" ' Create dumb 1x1 imagespace g.CreateImage 1,1,2 g.ReadImage filename,palette,0,0,True,frames_count if frames_count > 1 then ' Image is animated, do something end if 

##### How can I crop existing image?
Cropping is one of the easiest operations in ShotGraph. Just create imagespace (CreateImage method) having smaller size than original image and read image there (ReadImage method). The image will be cropped to imagespace borders. The top left corner coordinates parameters in the ReadImage method can accept negative coordinates: that allows to crop any part of image, not necessarily beginning from top left corner of original image. The scheme shows the process of reading 800x500 original image to 250x250 imagespace, so top left corner of imagespace is located at (100,100) point on original image.
 This script crops image to 250x250 starting at (100,100) point. Dim g Dim xcropsize,ycropsize,xstart,ystart,file_path,new_file_path Set g = CreateObject("shotgraph.image") file_path = "c:\images\original.jpg" new_file_path = "c:\images\newimage.jpg" xcropsize = 250 ycropsize = 250 xstart = 100 ystart = 100 ' Creating primary imagepace of neccessary size for cropped image g.CreateImage xcropsize,ycropsize,256 ' Reading image using negative coordinates g.ReadImage file_path,pal,-xstart,-ystart ' Saving cropped image to disk file g.JpegImage 90,0,new_file_path 

##### How can I build a line chart from SQL query?
There are many ways to do that. The examples of such charts are present on the page of examples. You can use those scripts as a basis for building your own scripts.

##### The images are stored in MS SQL (Oracle etc.) database. I would like to handle these images using shotgraph: retrieve image type and dimensions, resize etc. I don't want to swap images to temporary disk files. Is it possible?
Yes, with ShotGraph you have such opportunity. You can read the images from database as well as from usual disk files using GetFileDimensions and ReadImage methods. These methods accept not only file path as an image source, but also safearray containing image data. This feature can be used to retrieve images from database without temporary file (using ADO, for example).
 This example retrieves width and height of image stored in the database. Dim g,conn,rs,imagedata Dim xsize,ysize Set g = CreateObject("shotgraph.image") Set conn = CreateObject("ADODB.Connection") Set rs = conn.Execute("SELECT blobname FROM tablename WHERE Id=2") if not rs.eof then ' Get safearray   imagedata = rs.Fields(0).Value end if rs.Close g.GetFileDimensions imagedata,xsize,ysize ' Now xsize and ysize contain image dimensions 

##### How can I store images created by ShotGraph on the fly into MS SQL database without temporary file?
In case if file name is not specified, GifImage, JpegImage, PngImage and other such methods of ShotGraph returns variant variable containing safearray. It is one of standard supported types in COM. ADO can convert this type to any binary MS SQL data type: image, varbinary etc. To make such autoconversion, you can either:
- open ADO Recordset object using adLockOptimistic option, assign variable containing safearray to the Value property of recordset field and then call Update method of recordset.
or
- create a SQL stored procedure having parameter of image type. This is the preferred way.
 This example creates the image (black line on white background) and saves it into database table using stored procedure. The table has two fields: Id (int,IDENT) primary key ImageData (image) Set g = CreateObject("shotgraph.image") g.CreateImage 200,200,8 g.SetColor 0,255,255,255 g.SetColor 1,0,0,0 g.SetBgColor 0 g.SetDrawColor 0 g.FillRect 0,0,200,200 g.Line 0,0,200,200 img = g.GifImage(-1,0,"") ' Now img variable contains safearray with image Set cmd = CreateObject("ADODB.Command") Set conn = CreateObject("ADODB.Connection") conn.Open "Provider=sqloledb;Data Source=server1;Initial Catalog=mydatabase;" &_ "Integrated Security=SSPI" Set cmd.ActiveConnection = conn cmd.CommandText = "sp_AddImage" cmd.CommandType = 4 ' adCmdStoredProc ' Image assignment cmd.Parameters("@image").Value = img cmd.Execute Set cmd = Nothing Set conn = Nothing  CREATE PROCEDURE dbo.sp_AddImage @image image AS INSERT INTO ImgTable (ImageData) VALUES (@image) 

##### How can I save the image generated by ShotGraph to a disk file (in addition to sending image to client)
It's quite easy. You should take into account that ShotGraph represents image as safearray (suitable for Response.BinaryWrite). Therefore, you can save that array to the file using the WriteBinary function of ShotGraph.
 Your code before changing: <% Response.Contenttype="image/gif" Set g=CreateObject("shotgraph.image") ................... Response.BinaryWrite g.GifImage(-1,0,"") %>  Your code after changing: <% Response.Contenttype="image/gif" Set g=CreateObject("shotgraph.image") ................... img=g.GifImage(-1,0,"") Response.BinaryWrite img g.WriteBinary img,0,UBound(img)+1,"path\to\file.gif" %> 

##### How can I keep the transparency of resized GIF image?
There are two problems that make keeping transparency of resized GIF images slightly more complicated:
1. GIF file can contain more than one image with different transparency information.
2. The palettes of original GIF image and resized one can be different.
The following principles can be used to keep transparency of the resized image:
The ReadImage function reads the image from file using transparency information (unless the optional parameter is specified). Therefore, if you fill the imagespace with some rarely used color, that color will be visible through transparent areas. Later specify this color as transparent (the first parameter of GifImage) -- and your resized image will have the same transparent areas as original one. As a rule, the image are read into secondary imagespace for resizing. Accordingly, the secondary imagespace should be filled with background color just after creating.
 This example resizes (50%) a GIF image keeping transparency and palette size. <% path_to_file="c:\images\file.gif" Response.Contenttype="image/gif" Set g=CreateObject("shotgraph.image") g.GetFileDimensions path_to_file,xsize,ysize,palette xnewsize=xsize\2 ynewsize=ysize\2 palsize=256 if IsArray(palette) then palsize=UBound(palette)+1 g.CreateImage xnewsize,ysize,palsize ' Let this color be transparent g.SetColor 0,1,5,10 g.InitClipboard xsize,ysize g.SelectClipboard True g.SetBgColor 0 ' Fill the secondary imagespace with background g.FillRect 0,0,xsize-1,ysize-1 ' Read image using transparency g.ReadImage path_to_file,palette,0,0 g.Stretch 0,0,xnewsize,ynewsize,0,0,xsize,ysize,"SRCCOPY","HALFTONE" g.SelectClipboard False ' Color #0 remains untouched g.BuildPalette 1 ' Use color #0 as transparent one Response.BinaryWrite g.GifImage(0,0,"") %> 

##### Can I draw the foreign text (text with non-ANSI symbols)?
Yes, you can. There are two possible ways to do that (use one of them):
1.
The CreateFont function has the codepage parameter. To use it you should know the codepage number for the language (locale) of text.
2.
The CreateFont and TextOut functions have the optional parameter specifying whether to use Unicode strings. Turn Unicode representation on for TextOut (this parameter in CreateFont used only if font name contains foreign symbols). You should have the properly set the system (default) locale or @CODEPAGE ASP directive.

##### How can I alter the space between characters drawing the text string?
Although current version of Shotgraph does not support special methods/properties for changing space between characters in the strings drawn by TextOut method, you can easy reach that effect using simple procedure. The procedure can look like DrawString below. The procedure draws the string letter by letter calculating and summarizing the width of every char.
 This example shows the subroutine drawing text with altered character space <% Set g=CreateObject("shotgraph.image") Response.Contenttype="image/gif" Dim str str="EXAMPLE" g.CreateImage 200,200,4 g.SetColor 0,255,255,255 g.SetColor 1,0,0,0 g.SetTextColor 1 g.SetBgColor 0 g.FillRect 0,0,200,200 g.CreateFont "Arial Black",0,40,0,True,False,False,False DrawString 10,100,str,5 g.GifImage -1,0,"" ' This sub does the real job ' Parameters: ' x,y -- point to start the text ' str -- text string to draw ' sp -- the space between characters Sub DrawString(x,y,str,sp) Dim width,height,i,s,offset offset=0 for i=1 to Len(str) s=Mid(str,i,1) g.GetTextDimensions s,width,height g.TextOut x+offset,y,s offset=offset+width+sp Next End Sub %> 

##### I use other graphic component to create charts. It works good for me, however, I'd like to make some operation (watermarking etc.) that is absent in other component but present in ShotGraph. Can I "complete" with ShotGraph the image created by other component?
Yes, it is possible to use ShotGraph as addition to other component in cases when that component can write images into safearrays (suitable for Response.BinaryWrite) or into disk files. In the first case you can handle the image using ShotGraph without temporary disk files, because the GetFileDimensions and ReadImage methods accept not only file path as an image source, but also safearray containing image data.
 This example shows how to add a red diagonal line to the image created by some component. Dim chart,img,g,xsize,ysize,pal Set chart = CreateObject("Chart.Component") ' Here the component does main job ............... ' This string was: Response.BinaryWrite chart.WriteImage ' We store safearray into variable img = chart.WriteImage Set g = CreateObject("shotgraph.image") ' Create imagespace of necessary size g.CreateImage xsize,ysize,256 ' Declare color #1 as red g.SetColor 1,204,0,0 g.SetDrawColor 1 ' Read the chart into imagespace g.ReadImage img,pal,0,0 ' Draw the red line g.Line 0,0,xsize-1,ysize-1 ' Write the image to client Response.BinaryWrite g.JpegImage(95,0,"") 

##### How can I rotate image using ShotGraph?
You can easy rotate any existing (or virtually created in the imagespace) image using the SetTransformation method. The primary imagespace of necessary size for target image should be created first, and then the image is read into secondary imagespace. The Copy method will perform real rotation.
 This example rotates the image 90 degrees counter-clockwise. Error checkings are omitted. Dim xsize, ysize, filepath, new_filepath, g ' Source file path filepath = "c:\sourceimage.jpg" ' Target file path new_filepath = "c:\rotated_sourceimage.jpg" Set g = CreateObject("shotgraph.image") ' Get width and height of source file g.GetFileDimensions filepath,xsize,ysize ' Create primary imagespace with replaced dimensions, ' because image will be rotated 90° g.CreateImage ysize, xsize, 256 g.SetGraphicsMode "GM_ADVANCED" ' Set parameters for rotating image 90° counter-clockwise g.SetTransformation 0, -1, 1, 0, 0, xsize ' Create secondary imagespace for source image g.InitClipboard xsize,ysize g.SelectClipboard True ' Read the source image into secondary imagespace g.ReadImage filepath, aPalette, 0, 0 ' Rotate the image g.Copy 0,0,xsize,ysize,0,0,"SRCCOPY" g.SelectClipboard False ' Writing new image into file g.JpegImage 95,0,new_filepath 

##### How can I draw text in circular format (like in a rubber stamp)?
To make such effect with text you need to create a simple prodedure that draws text string char by char placing every char into necessary position and creating font with required angle.
 This example shows the procedure CircularText. It accepts source text string, coordinates and size of circle, start angle of text and size of text in degrees. The result of this procedure is shown here. ' Source file path Const pi = 3.141 Set g = CreateObject("shotgraph.image") g.CreateImage 320,240,8 g.SetColor 0,255,255,255 g.SetColor 1,0,0,104 g.SetBgColor 0 g.FillRect 0,0,320,240 g.SetTextColor 1 g.SetBkMode "TRANSPARENT" g.SetTextAlign "TA_CENTER","TA_BASELINE" CircularText "Test string",160,200,100,0,180 g.JpegImage 90,0,"circular.jpg" ' Angle is calculated from horizontal line ' on left hand side from the center (clockwise) in degrees Sub CircularText(text,xcenter,ycenter,radius,start_angle,text_angle) Dim step_angle, amount, i, angle amount = Len(text) - 1 if amount <= 0 then amount = 1 angle = start_angle * pi / 180.0 step_angle = pi * text_angle / amount / 180.0 for i=1 to Len(text) g.CreateFont "Arial",0,32,_ 900-(start_angle*10.0 + text_angle*10.0/amount*(i-1)),_ True,False,False,False g.TextOut xcenter-radius*Cos(angle),ycenter-radius*Sin(angle),_ Mid(text,i,1) angle = angle + step_angle Next End Sub 

 © 1998-2001 Mikhail Tchikalov Email to contact: mtchikalov@usa.com