Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Alexander Windel
Microsoft Corporation
December 2003
Applies to:
Microsoft® Windows® SharePoint™ Services
Microsoft Office SharePoint Portal Server 2003
Summary: Simplify copyright protection for your picture library images with built-in Web services for Microsoft SharePoint Products and Technologies. This article describes how to create a sample client application allowing you to embed watermarks into images when uploading them to a picture library on a SharePoint site.
This article assumes that you have a basic understanding of the Microsoft .NET Framework and a programming language such as Microsoft Visual Basic®.NET. For additional reference material not included in this article, see the Microsoft SharePoint Products and Technologies Software Development Kit (SDK). (14 printed pages)
Note The information in this article also applies to Microsoft Office SharePoint Portal Server 2003, which is built on the Windows SharePoint Services platform.
Introduction
Creating the Watermark Application
Conclusion
Microsoft® Windows® SharePoint™ Services includes many built-in Web services offering new, powerful ways to integrate business processes. At the same time, copyright is an issue which is getting more and more important for enterprises.
Using the Imaging Web service in a sample application provides a great way to automate the complete process of retrieving images from local or remote sources, embedding a unique watermark into these images and then, populating a picture library with those customized images.
You must be a member of the Contributor site group on the server that is running Windows SharePoint Services to run the watermark Web service client for the Imaging Web service on an existing picture library. To create the picture library on the SharePoint site, you must be a member of the Web Designer site group. To compile the sample application without customizations, you need to download the Microsoft .NET Framework version 1.1. Microsoft Visual Studio® .NET 2003 already includes this version of the Microsoft .NET Framework.
The following list outlines the process for retrieving images, embedding a watermark, and uploading them to a picture library by using Web services. The remainder of the article reviews this process in detail.
- Using Visual Studio .NET, create a Windows Application Project, write code to scan your computer for local image files and populate a ListView control with the results. If required, add remote image files, for example from another Web service on the WWW, to your local list of pictures.
- Write code to embed a unique watermark, e.g. based on the current user name, into the images by taking advantage of the DrawString method.
- Generate a Web service proxy class for your Imaging Web service by adding a Web Reference in Visual Studio .NET. The Web service URL should be similar to: http://server_name/_vti_bin/Imaging.asmx
- Make sure that your picture library exists, and then use the Upload Web method to transfer the images to the picture library.
To create a sample watermark application for a picture library, use the following methods in the order in which they are presented.
To create the GUI of the sample Windows Application Project in Visual Studio .NET 2003
On the File menu, point to New, and then click Project.
In the Project Types box, click Visual Basic Projects.
In the Templates box, click Windows Application.
Specify a name and location for the project and then click OK.
In the Toolbox window, add a MainMenu and a TabControl component to Form1. By default these controls are named MainMenu1 and TabControl1.
In the Properties window of the TabControl control, open the TabPage Collection Editor and configure the TabPage collection to have two members, TabPage1 and TabPage2.
Change the Text property of TabPage1 to Local image source and rename the Text property of TabPage2 to Remote Image source.
In the Design Window for****Form1, click MainMenu1 and then click the Type here box on the menu bar.
Add three top-level menu items.
In the Type here box for each item, add the following descriptions:
- For item 1 type, Explore current batch folder content.
- For item 2 type, Start batch upload to picture library.
- For item 3, type, Exit.
Add three LinkLabel controls to TabPage1.
Change the Text property of the LinkLabel1 to Start Scanning.
Change the Text property of the LinkLabel2 to Stop Scanning.
Change the Text property of LinkLabel3 to Copy Selected Images to Batch Folder.
Add one Label control, one Button control, and a ListView control to TabPage1.
Change the Text property of Label1 to Processing. . . and in the Properties window, set the Visible property to False at Design time.
Change the Text property of Button1 to Change folder.
Change the View property of ListView1 to List.
Figure 1. First tab of completed form
Add a FolderBrowserDialog control to Form1.
Note The FolderBrowserDialog control requires the Microsoft .NET Framework version 1.1.
Add a PictureBox control, a Label control, a LinkLabel control and a TextBox control to TabPage2.
Place Label2 above the TextBox1 control.
Change the Text property of Label2 to Scale and the Text property of LinkLabel4 to Get image from database.
Set the Text property of TextBox1 to 0.396127. This determines the scale of the retrieved image in arcsec/pixel.
Figure 2. Second tab of completed form
Note Depending on your regional options you may need to modify the string to use a comma instead of a period, leading to 0,396127 as the default value.
You can now add the code to scan for local images or retrieve remote images.
To scan for image files and copy them to the Batch Upload folder
Add the following imports directive to your Windows Application project.
Imports System.IO
We need a Boolean variable for LinkLabel2 functionality such as Stop scanning to work. Therefore, add the following declaration to the Form1 class.
Dim interrup As Boolean
We also need a procedure which accepts a path string and then searches all files and subfolders for existing image files. Add the following recursive procedure to the Form1 class code to accomplish this requirement.
Private Sub SearchImages(ByVal Path As String) If interrup Then Exit Sub Try Dim fInfo As FileInfo Dim dInfo As DirectoryInfo Dim currdir As DirectoryInfo = New DirectoryInfo(Path) Dim mydirectories() As DirectoryInfo = currdir.GetDirectories Dim myfiles() As FileInfo = currdir.GetFiles For Each dInfo In mydirectories SearchImages(dInfo.FullName) Next For Each fInfo In myfiles If interrup = False Then If LCase(fInfo.Extension) = ".gif" _ Or LCase(fInfo.Extension) = ".bmp" _ Or LCase(fInfo.Extension) = ".jpg" _ Or LCase(fInfo.Extension) = ".jpeg" _ Or LCase(fInfo.Extension) = ".png" _ Or LCase(fInfo.Extension) = ".tif" _ Or LCase(fInfo.Extension) = ".tiff" _ Or LCase(fInfo.Extension) = ".gif" _ Or LCase(fInfo.Extension) = ".pcd" _ Or LCase(fInfo.Extension) = ".pcx" _ Then ListView1.Items.Add(fInfo.FullName) End If Else Exit For End If Application.DoEvents() Next Catch xx As Exception MessageBox.Show(xx.Message, "Error", _ MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub
In the Load event procedure for Form1, add the following code.
Note This procedure sets the defaults of FolderbrowserDialog1.SelectedPath and LinkLabel1.Text to point to the My Pictures folder. If necessary, it creates the ImagesToBeShared folder that contains all the files to be uploaded in a batch to the specified picture library as specified by the URL property of the Imaging Web service. The usage of Environment.SpecialFolder.MyPictures as well as the FolderBrowserDialog control requires the Microsoft .NET Framework version 1.1.
Dim drives() As String Dim mypic As String Try mypic = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) FolderBrowserDialog1.SelectedPath = mypic LinkLabel1.Text = "Start Scanning " & FolderBrowserDialog1.SelectedPath If Not (Directory.Exists(mypic & "\ImagesToBeShared")) Then Directory.CreateDirectory(mypic & "\ImagesToBeShared") End If Catch xx As Exception MessageBox.Show(xx.Message, "Error", _ MessageBoxButtons.OK, MessageBoxIcon.Error) End End Try
In the LinkClicked event procedure for LinkLabel1, add the following code.
Note If you click the LinkLabel1 ("Start scanning") the selected local path and all of its subdirectories are searched for image files by calling the SearchImages procedure.
Try interrup = False ListView1.Visible = False Label1.Visible = True ListView1.Items.Clear() Me.Cursor = Cursors.WaitCursor SearchImages(FolderBrowserDialog1.SelectedPath.ToString) ListView1.Visible = True Me.Cursor = Cursors.Default Label1.Visible = False If ListView1.Items.Count <= 0 Then MessageBox.Show("No files were found!", _ "File not found", _ MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Else MessageBox.Show("Scanning finished.", "Done", _ MessageBoxButtons.OK, MessageBoxIcon.Information) End If Catch xx As Exception MessageBox.Show(xx.Message, "Error", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Finally ListView1.Visible = True Label1.Visible = False Me.Cursor = Cursors.Default End Try
In the LinkClicked event procedure for LinkLabel2, add the following code.
Note This indicates to the SearchImages procedure that local file searching should be cancelled.
interrup = True
We need some code to copy all selected items from ListView1 to the image batch folder at . . .
\My Pictures\ImagesToBeShared
. In the LinkClicked event procedure for LinkLabel3, we therefore add the following code:Dim PicDir As String Dim LItem As ListViewItem Dim LItems As ListView.SelectedListViewItemCollection Dim i As Integer Try PicDir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) If Not (Directory.Exists(PicDir & "\ImagesToBeShared")) _ Then Directory.CreateDirectory(PicDir & "\ImagesToBeShared") End If If ListView1.SelectedItems.Count <= 0 Then MessageBox.Show("No Items selected!", _ "Item not found", MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Try End If LItems = ListView1.SelectedItems Me.Cursor = Cursors.WaitCursor For i = 0 To LItems.Count - 1 Try LItem = LItems(i) File.Copy(LItem.Text.ToString, PicDir & _ "\ImagesToBeShared\" & _ Path.GetFileName(LItem.Text.ToString)) Catch xx As Exception MessageBox.Show(xx.Message, "Error", _ MessageBoxButtons.OK, MessageBoxIcon.Error) End Try Next Me.Cursor = Cursors.Default MessageBox.Show("Finished copying files to " _ & PicDir & "\ImagesToBeShared.", "Done", _ MessageBoxButtons.OK, MessageBoxIcon.Information) Catch xx As Exception MessageBox.Show(xx.Message, "Error", _ MessageBoxButtons.OK, MessageBoxIcon.Error) Finally Me.Cursor = Cursors.Default End Try ListView1.Items.Clear()
In the Click event procedure for Button1, add this code.
Try FolderBrowserDialog1.ShowDialog() LinkLabel1.Text = _ "Start Scanning " & FolderBrowserDialog1.SelectedPath Catch xx As Exception MessageBox.Show(xx.Message, _ "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
Now that we added the required code to copy local image files to our Upload folder, we want to add some remote images, too. For the sample code to work, add a Web reference to the Image CutOut Web service of the publicly available Sky Digital Space Survey (SDSS) database. For more information about the SDSS database we make use of here, see SDSS SkyServer
.
In Solution Explorer, right-click the project, and then click Add Web Reference.
In the wizard, type the following URL, and then click Open to download the service contract for the Web service:
http://skyservice.pha.jhu.edu/dr1/ImgCutout/imgcutout.asmx
Note While adding the Web reference, if you receive the error message "The underlying connection was closed: The remote name could not be resolved" then you need to modify the proxy settings in your machine.config file. For more information, see the following articles:
Name this Web reference SDSS_Images.
Now we need add code that adds an image from the Image CutOut Web service to PictureBox1. For the sake of simplicity, we assign fixed values to most of the variables except the scale of the image retrieved. With regard to the location in space, ra is the right ascension and dec is the declination in degrees. The imageoptions value is set to return a grid and some descriptive labels as part of the image. Add the code below to the LinkClicked event procedure of LinkLabel4.
Try Dim JpgContent() As Byte Dim JpgStream As FileStream Dim res As DialogResult Dim PicDir As String Dim jpgname As String Dim ra As Double = 184.9511 Dim dec As Double = -0.8754 Dim imagewidth As Integer = 350 Dim imageheight As Integer = 350 Dim imageoptions As String = "GL" Dim scale As Double If IsNumeric(TextBox1.Text) Then scale = CDbl(TextBox1.Text) Else scale = 0.396127 End If Dim SpaceImages As New SDSS_Images.ImgCutout SpaceImages.Timeout = 20000 PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize jpgname = _ InputBox("Choose file name without extension: ", _ "New file name") If jpgname = "" Then Exit Try jpgname = Path.GetFileNameWithoutExtension(jpgname) & ".jpg" PicDir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) If Not (Directory.Exists(PicDir & "\ImagesToBeShared")) Then Directory.CreateDirectory(PicDir & "\ImagesToBeShared") End If If File.Exists(PicDir & "\ImagesToBeShared\" & jpgname) Then MessageBox.Show("File already exists", _ "File already exists", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Exit Try Else Me.Cursor = Cursors.WaitCursor JpgStream = File.Create(PicDir & _ "\ImagesToBeShared\" & jpgname) End If JpgContent = SpaceImages.GetJpeg(ra, dec, scale, imagewidth _ , imageheight, imageoptions) Dim w As New BinaryWriter(JpgStream) w.Write(JpgContent) JpgStream.Close() w.Close() PictureBox1.Image = PictureBox1.Image.FromFile(PicDir _ & "\ImagesToBeShared\" & jpgname) PictureBox1.Refresh() Me.Cursor = Cursors.Default Catch xx As Exception MessageBox.Show(xx.Message, "Error", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Finally Me.Cursor = Cursors.Default End Try
In the Click event procedure for MenuItem1, add the following code.
Dim ProcID As Integer Try ProcID = Shell("explorer.exe " & _ Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) & _ "\ImagesToBeShared", AppWinStyle.NormalFocus) Catch xx As Exception MessageBox.Show(xx.Message, "Error", _ MessageBoxButtons.OK, MessageBoxIcon.Error) End Try
Add a Web reference to the Imaging Web service.
Right-click the project in Solution Explorer, and then click Add Web Reference.
In the wizard, type the following URL, and then click Open to download the service contract for the Web service:
http://
Server_name/_vti_bin/Imaging.asmx
Name this Web reference ImagingService.
In the Click event procedure for MenuItem2, add the following code.
Note This instantiates an ImageList object of the proxy class of the Imaging Web service for the SharePoint site and uses the DrawString method on a Graphics object to add watermarks. The color of the SolidBrush object being applied to the watermarks is chosen for use with images with a dark background such as those retrieved from the SDSS Web service. Last but not least the procedure invokes the Upload Web method to transfer all images of the Watermark folder to the root folder of the picture library named Shared Images. Existing files are overridden as specified by the fOverwriteIfExist parameter of the method. The time-out value is set to 20 seconds to prevent network bottleneck issues. The Credentials property is configured to use default credentials, e.g. Integrated Windows Authentication.
Dim PicDir As String Dim i As Long Dim AllFiles() As String Dim FStream As FileStream Dim res As DialogResult Dim wm As String Try Dim ImageList As New ImagingService.Imaging PicDir = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) If Not (Directory.Exists(PicDir & "\ImagesToBeShared")) Then Directory.CreateDirectory(PicDir & "\ImagesToBeShared") MessageBox.Show("WSS Batch Upload directory not found" & _ "- recreated directory!", "Directory not found", _ MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Exit Try End If If Directory.GetFiles(PicDir & "\ImagesToBeShared").Length = 0 _ Then MessageBox.Show("No files to upload!", "File not found", _ MessageBoxButtons.OK, MessageBoxIcon.Exclamation) Exit Try End If AllFiles = Directory.GetFiles(PicDir & "\ImagesToBeShared") res = MessageBox.Show("Your files will be uploaded to " & _ ImageList.Url.ToString & ". Proceed?", "Confirm Upload", _ MessageBoxButtons.OKCancel, MessageBoxIcon.Question) If res = DialogResult.OK Then ImageList.Credentials = _ System.Net.CredentialCache.DefaultCredentials ImageList.Timeout = 20000 Me.Cursor = Cursors.WaitCursor If Not Directory.Exists(PicDir & "\watermark") Then Directory.CreateDirectory(PicDir & "\watermark") End If PictureBox1.Visible = False PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize For i = 0 To AllFiles.Length - 1 Try PictureBox1.Image = _ PictureBox1.Image.FromFile(AllFiles(i).ToString) Dim bmp As New _ Bitmap(PictureBox1.Width, PictureBox1.Height) bmp.SetResolution(PictureBox1.Image.HorizontalResolution, _ PictureBox1.Image.VerticalResolution) Dim gra As Graphics = Graphics.FromImage(bmp) gra.DrawImage(PictureBox1.Image, 0, 0) gra.DrawString(Environment.UserName, _ PictureBox1.Font, New _ SolidBrush(Color.FromArgb(130, 255, 0, 0)), 0, 0) gra.Dispose() wm = PicDir & "\watermark\" & _ Path.GetFileName(AllFiles(i).ToString) bmp.Save(wm) bmp.Dispose() FStream = File.OpenRead(wm) Dim r As New BinaryReader(FStream) Dim FContent(FStream.Length - 1) As Byte FContent = r.ReadBytes(FStream.Length) ImageList.Upload("Shared Images", "", _ FContent, Path.GetFileName(wm), True) r.Close() Catch xx As Exception MessageBox.Show("The file " & AllFiles(i).ToString & " cannot be processed.", "Warning", _ MessageBoxButtons.OK, MessageBoxIcon.Warning) End Try Next PictureBox1.Visible = True Me.Cursor = Cursors.Default MessageBox.Show("Uploading files finished.", _ "Done", MessageBoxButtons.OK, MessageBoxIcon.Information) End If Catch xx As Exception MessageBox.Show(xx.Message, "Error", MessageBoxButtons.OK, _ MessageBoxIcon.Error) Finally Me.Cursor = Cursors.Default PictureBox1.Visible = True End Try
In the Click event procedure for MenuItem3, add the following line of code.
End
Now we've got all necessary code to run our sample. Compile the project. Before running the sample application, verify that a picture library named Shared Images exists on the SharePoint site and that you have the necessary permissions for the picture library.
In this article you learned how you can effectively integrate the Upload web method of the Imaging Web service of Windows SharePoint Services into a sample application allowing you to embed watermarks into images at upload time. Using watermarks for your picture libraries as a method to ensure copyright enhances the power and security of data stored on a SharePoint site.