Click here to Skip to main content
15,886,067 members
Articles / AddIn
Tip/Trick

Use VBA to Make a Picture Transparent in Microsoft Office

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
8 Nov 2015CPOL3 min read 26K   6   4
Why can't you set transparency to a picture in an MSOffice application? Well, you can use a clumsy work-around to create a shape and paste your picture from the clipboard. Here's the code to automate it from VBA.

Introduction

I have often wondered why you cannot simply set the transparency of a picture you paste in PowerPoint. Unless you are prepared to paste the picture into a rectangle shape and use the fill command 'paste from clipboard', there is no way to do it. In this tip, I'll show how to use simple VBA to achieve this. I have the code running from a button in a ribbon to work on a selected picture in a PowerPoint slide:

Image 1

but the code should work with any shape from the ShapeCollection in any MSOffice app.

Using the Code

The core routine is a sub which acts on a selected object in PowerPoint (working for versions 2010 and 2013) called makeTransp(keepOriginal As Boolean) in a code module. I run the routine from a button from a custom ribbon. The code looks for a current selection of shapes in Powerpoint. In the code snippets following the core routine, I'll show how to set up the trapping of the selection events in PowerPoint.

First, the routine will check if there are any shapes selected and, secondly, if the first selected shape is of type msoPicture. If this isn't the case, the sub exits silently or with a warning.

If the routine finds a usable picture, it will export the shape to a temp image file. The reason for this is the fact that a newly created (rectangle) shape can only be filled using fillmode 'UserPicture'. Once the picture has been exported, I create a new shape on the current slide with AddShape using the dimensions of the original picture. Depending on the switch to keep the original picture or not, I offset the new shape by 10 units. As is the custom with pictures, I lock the AspectRatio by default. Subsequently, I fill the new shape with the image from the file and put the fill's transparency to 50%. The user him/herself can then go to the properties of the new shape and tweak the transparency further. Depending on the switch keepOriginal I delete the original picture. Lastly, I clean up the temp image file.

Core routine in code module1:

VB.NET
'VBA code:
Private Sub makeTransp(keepOriginal As Boolean)
    If currentApp.SelectedShapes Is Nothing Then Exit Sub
    If currentApp.SelectedShapes.Count < 1 Then Exit Sub
    
    Dim s As Shape
    Set s = currentApp.SelectedShapes(1)
    
    If s.Type <> msoPicture Then
        MsgBox "Selected object is not an image or picture", _
        	vbExclamation, "Office Tools"
    Else
        Dim fname As String
        fname = Environ("Temp") & "\tmpimagename.jpg"
        'Debug.Print "exporting image to: " & fname
        s.Export fname, ppShapeFormatJPG
        
        Dim sld As Slide
        Set sld = Application.ActiveWindow.View.Slide
        
        Dim shp As Shape
        Dim offset As Integer
        offset = 0
        If keepOriginal Then
            offset = 10
        End If
        Set shp = sld.Shapes.AddShape(Type:=msoShapeRectangle, _
                     Left:=s.Left + offset, Top:=s.Top + offset, _
                     Width:=s.Width, Height:=s.Height)
        shp.LockAspectRatio = msoTrue
        shp.Fill.UserPicture (fname)
        shp.Fill.Transparency = 0.5
        deleteFile fname
        If Not keepOriginal Then
            s.Delete
        End If
    End If
End Sub

In the above routine, the currentApp class holds the runtime info on any current selection. This class is called rpvEvents and is declared WithEvents in a class module within the same VBA project:

VB.NET
'VBA code:
Public WithEvents App As Application
Public SelectedShapes As ShapeRange

Private Sub App_WindowSelectionChange(ByVal sel As Selection)
    With sel
        If .Type = ppSelectionShapes Then
            'Debug.Print "shape selected"
            Set SelectedShapes = sel.ShapeRange
        Else
            Set SelectedShapes = Nothing
        End If
    End With
End Sub

The class is initialized when the code of module1 is loaded:

VBScript
'VBA code:
Option Explicit
Dim currentApp As New rpvEvents

Public Sub rpvOnLoad()
    Debug.Print "initialize 6nov2015..."

    'start a new application event handler
    Set currentApp.App = Application
End Sub

The little routine to delete the tempfile looks like this in module1:

VB.NET
'VBA code:
Private Sub deleteFile(path As String)
    On Error Resume Next
    Kill path
End Sub

An example of an original image copied into a transparent shape is shown here (smart readers will guess my home country... it's a dead give-away):

Image 2

Points of Interest

VBA isn't my native language (VB.NET is) and it is obviously very much the ugly little sister in the various language families. However, I make use of it once in a while when I need to automate my work with MSOffice. And you can make your colleagues happy with a simple macro they can use every day.

History

My first article on my first topic.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer VeeTools
Netherlands Netherlands
A (usually exploring) geologist who sometimes develops software for fun and colleagues... Check out my new website at www.veetools.xyz for online mapping and coordinate conversion.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Gustav Brock25-Nov-15 20:44
professionalGustav Brock25-Nov-15 20:44 
AnswerRe: My vote of 5 Pin
veen_rp26-Nov-15 20:43
professionalveen_rp26-Nov-15 20:43 
GeneralRe: My vote of 5 Pin
veen_rp26-Nov-15 20:54
professionalveen_rp26-Nov-15 20:54 
On the other hand: I found that with the newest release of office, the event handler doesn't work anymore. Don't know why yet... and I have no time to find it out in the short term. So I resorted in my version to:
VB
ActiveWindow.Selection.ShapeRange

as opposed to:
VB
currentApp.SelectedShapes


More specific, the part that doesn't work anymore is this:
VB
'Class rpvEvents
Public WithEvents App As Application
Public SelectedShapes As ShapeRange

Private Sub App_WindowSelectionChange(ByVal sel As Selection)
    With sel
        If .Type = ppSelectionShapes Then
            'Debug.Print "shape selected"
            Set SelectedShapes = sel.ShapeRange
        Else
            Set SelectedShapes = Nothing
        End If
    End With
End Sub

GeneralRe: My vote of 5 Pin
Gustav Brock26-Nov-15 21:51
professionalGustav Brock26-Nov-15 21:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.