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
  1. How can I tell animated Gif from static one?
  2. How can I crop existing image?
  3. How can I build a line chart from SQL query?
  4. 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?
  5. How can I store images created by ShotGraph on the fly into MS SQL database without temporary file?
  6. How can I save the image generated by ShotGraph to a disk file (in addition to sending image to client)
  7. How can I keep the transparency of resized GIF image?
  8. Can I draw the foreign text (text with non-ANSI symbols)?
  9. How can I alter the space between characters drawing the text string?
  10. 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?
  11. How can I rotate image using ShotGraph?
  12. How can I draw text in circular format (like in a rubber stamp)?
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