How to Insert, Move & Delete Pictures with VBA

While it is not often that we have to control pictures or images within Excel, based on the number of Google searches for this topic, it’s clearly something people want to know more about. This post serves as a reference to cover most of the scenarios we’re likely to encounter to copy, insert, move, delete and control pictures.

This code can be used in conjunction with my post about using a user defined function to insert and change pictures based on a cell value, which can be found here: https://exceloffthegrid.com/automatically-change-picture/

Table of Contents

Download the example file: Join the free Insiders Program and gain access to the example file used for this post.

File name: 0042 VBA copy, insert, move, delete pictures.zip

Adapting the code to your needs

It is unlikely that any of the codes will meet your exact requirements. Every code snippet uses variables to hold either the image, the worksheet, a range or an object.  By changing those variables, the code can easily be changed and combined with other code snippets to meet your specific requirements.

Insert an image into a worksheet

The following code will insert an image into the active cell of the active worksheet, keeping the original image’s size.

Sub InsertImage()

Dim ws As Worksheet
Dim imagePath As String
Dim imgLeft As Double
Dim imgTop As Double

Set ws = ActiveSheet
imagePath = "C:\Users\marks\Documents\myImage.png"
imgLeft = ActiveCell.Left
imgTop = ActiveCell.Top

'Width & Height = -1 means keep original size
ws.Shapes.AddPicture _
    fileName:=imagePath, _
    LinkToFile:=msoFalse, _
    SaveWithDocument:=msoTrue, _
    Left:=imgLeft, _
    Top:=imgTop, _
    Width:=-1, _
    Height:=-1
 
End Sub

Depending on our needs, it may be better to create an image straight into an object variable.  Then we can refer to the image by using the variable and do not need to know the name of the image.  The following code is an example of this technique.

Sub InsertImageToDeclaredVariable()

Dim myImage As Shape
Dim ws As Worksheet
Dim imagePath As String
Dim imgLeft As Double
Dim imgTop As Double

Set ws = ActiveSheet
imagePath = "C:\Users\marks\Documents\myImage.png"
imgLeft = ActiveCell.Left
imgTop = ActiveCell.Top

Set myImage = ws.Shapes.AddPicture( _
    Filename:=imagePath, _
    LinkToFile:=msoFalse, _
    SaveWithDocument:=msoTrue, _
    Left:=imgLeft, _
    Top:=imgTop, _
    Width:=-1, _
    Height:=-1)

'Use the variable for the created image
MsgBox myImage.Name

End Sub

Image names

The code below will display the name of the last inserted image.

The message box is to illustrate that the code works.  Once we have captured the shape as an object in the real world, we would perform other actions on the shape.

Sub GetNameOfLastInsertedImage()

Dim myImage As Shape

Set myImage = ActiveSheet.Shapes(ActiveSheet.Shapes.Count)

MsgBox myImage.Name

End Sub

The code below renames an existing image.

Sub RenameImage()

Dim myImage As Shape
Dim ws As Worksheet

Set ws = ActiveSheet
Set myImage = ws.Shapes("Picture 2")

myImage.Name = "New Image Name"

End Sub

Get image properties

The following code demonstrates how to retrieve common image properties

Sub GetImageProperties()

Dim myImage As Shape
Dim ws As Worksheet

Set ws = ActiveSheet
Set myImage = ws.Shapes("Picture 1")

MsgBox "Top: " & myImage.Top & vbNewLine & _
    "Left: " & myImage.Left & vbNewLine & _
    "Width: " & myImage.Width & vbNewLine & _
    "Height: " & myImage.Height & vbNewLine & _
    "Z-Order: " & myImage.ZOrderPosition & vbNewLine & _
    "Name: " & myImage.Name & vbNewLine & _
    "Top Left Cell: " & myImage.TopLeftCell & vbNewLine

End Sub

Delete an image

The following code will delete an image called Picture 1 from the active worksheet.

Sub DeleteImage()

Dim myImage As Shape
Dim ws As Worksheet

Set ws = ActiveSheet
Set myImage = ws.Shapes("Picture 1")

myImage.Delete

End Sub

Make images invisible

Images can be made invisible.  They still exist and are part of the workbook, but they are not visible to the user.

Sub MakeImageInvisible()

Dim myImage As Shape
Dim ws As Worksheet

Set ws = ActiveSheet
Set myImage = ws.Shapes("Picture 1")

myImage.Visible = msoFalse

'Make the image visible again
'myImage.Visible = msoTrue

End Sub

Loop through all images on a worksheet

The following code will loop through all the images on the active sheet.

Sub LoopThroughImagesOnWs()

Dim shp As Shape
Dim ws As Worksheet

Set ws = ActiveSheet

For Each shp In ws.Shapes

    If shp.Type = msoPicture Then
 
        'Do something to the image
        'Example, show message box
        MsgBox shp.Name & " is a picture"
 
    End If

Next shp

End Sub

Confirm if the selected object is a picture

The code below will check if a specific object is a Picture.

Sub CheckIfSelectionIsPicture()

Dim thing As Object
Set thing = Selection

If TypeName(thing) = "Picture" Then
    MsgBox "Selection is a picture"
Else
    MsgBox "Selection is NOT a picture"
End If

End Sub

Linked pictures

Images can be linked to cells or named ranges.  This makes the image dynamic; when the contents of the cells change, so does the picture.

Sub MakeImageLinkedPicture()

Dim ws As Worksheet

Set ws = ActiveSheet

ws.Pictures("Picture 1").Formula = "=A1:D10"

End Sub

Image placement and locking options

Image behavior can be controlled using the placement option.

Sub ImagePlacementAndLockingOptions()

Dim myImage As Shape
Dim ws As Worksheet

Set ws = ActiveSheet
Set myImage = ws.Shapes("Picture 1")

'Image placement options
myImage.Placement = xlFreeFloating
'The other placement options are:
'xlMoveAndSize
'xlMove

'Locking images (prevent editing image when worksheet protected)
myImage.Locked = True
'The other placement options are:
'myImage.Locked = False

End Sub

Rotate images

The following code rotates the image by a specific amount

Sub RotateImageIncremental()

Dim myImage As Shape
Dim rotationValue As Integer

Set myImage = ActiveSheet.Shapes("Picture 1")
rotationValue = 45

'Rotate the image by the amount specified by the rotationValue
myImage.IncrementRotation (rotationValue)

End Sub

The following code rotates the image to a specific amount.

Sub RotateImageAbsolute()

Dim myImage As Shape
Dim rotationValue As Integer

Set myImage = ActiveSheet.Shapes("Picture 2")
rotationValue = 90

'Rotate the image to the amount specified by the rotationValue
myImage.rotation = rotationValue

End Sub

Set image position to the center of a cell

An image is positioned based on the top and left of that image. The following code will set the position so that it appears centered within a specific cell.

Sub CenterInCell()

Dim myImage As Shape
Dim cellLocation As Range

Set myImage = ActiveSheet.Shapes("Picture 1")
Set cellLocation = ActiveSheet.Range("B4")

myImage.Top = cellLocation.Top + (cellLocation.Height / 2) - (myImage.Height / 2)
myImage.Left = cellLocation.Left + (cellLocation.Width / 2) - (myImage.Width / 2)

End Sub

Flipping an image horizontally or vertically

Flip the image horizontally:

Sub FlipImageHorizontal()

Dim myImage As Shape
Set myImage = ActiveSheet.Shapes("Picture 1")

myImage.Flip msoFlipHorizontal

End Sub

Flip the image vertically:

Sub FlipImageVertical()

Dim myImage As Shape
Set myImage = ActiveSheet.Shapes("Picture 1")

myImage.Flip msoFlipVertical

End Sub

Resize an image

The code below locks the aspect ratio; therefore, resizing the width or height will maintain the image’s proportions.

Sub ResizeImageLockAspectRatio()

Dim myImage As Shape
Dim imageWidth As Double

Set myImage = ActiveSheet.Shapes("Picture 1")
imageWidth = 100

myImage.LockAspectRatio = msoTrue
myImage.Width = imageWidth

End Sub

When setting the aspect ratio to msoFalse, the height and width operate independently.

Sub ResizeImageHeightOrWidth()

Dim myImage As Shape
Dim imageWidth As Double
Dim imageHeight as Double

Set myImage = ActiveSheet.Shapes("Picture 1")
imageWidth = 100
imageHeight = 50

myImage.LockAspectRatio = msoFalse
myImage.Width = imageWidth
myImage.Height = imageHeight

End Sub

The following code positions an image and stretches it to perfectly cover a specified range.

Sub StretchImageToCoverCells()

Dim myImage As Shape
Dim ws As Worksheet
Dim rng As Range

Set ws = ActiveSheet
Set myImage = ws.Shapes("Picture 1")
Set rng = ws.Range("A2:D10")

myImage.LockAspectRatio = msoFalse

myImage.Left = rng.Left
myImage.Top = rng.Top
myImage.Width = rng.Width
myImage.Height = rng.Height

End Sub

Cropping

The code below crops an image based on the distance from the top, left, bottom or right.

Sub CropImage()

Dim myImage As Shape
Set myImage = ActiveSheet.Shapes("Picture1")

myImage.PictureFormat.CropLeft = 50
myImage.PictureFormat.CropTop = 50
myImage.PictureFormat.CropRight = 50
myImage.PictureFormat.CropBottom = 50

End Sub

Changing Z-Order

The image can be moved forward or backward within the stack of objects (known as the Z-Order).

Sub ChangeZOrderRelative()

Dim myImage As Shape

Set myImage = ActiveSheet.Shapes("Picture 1")

myImage.ZOrder msoBringForward

'Alternative send backward
'myImage.ZOrder msoSendBackward

End Sub

The Z-Order position cannot be set directly. First, send the image to the back, then move the image forward with a loop.  Continue looping until the image reaches the correct Z-Order Position.

Sub ChangeZOrderAbsolute()

Dim myImage As Shape
Dim imageWidth As Double
Dim imageZPosition As Integer

Set myImage = ActiveSheet.Shapes("Picture 1")
imageZPosition = 3

'Force z-order to zero then bring forward
myImage.ZOrder msoSendToBack

Do While myImage.zOrderPosition < imageZPosition

    myImage.ZOrder msoBringForward

Loop

End Sub

Set the background image

The background image appears behind the cells in the spreadsheet.

Sub SetImageBackground()

Dim ws As Worksheet
Dim imgPath As String

Set ws = ActiveSheet
imgPath = "C:\Users\marks\Documents\myImage.png"

ws.SetBackgroundPicture fileName:=imgPath

'Remove the background image
'ws.SetBackgroundPicture fileName:="

End Sub

Save picture from Excel

If we have a picture in an Excel workbook, there is no straightforward way to save it to disk as a picture.  A common workaround is to set the picture as the background of a chart area, then export the chart as an image.

Sub SavePictureFromExcel()

Dim myPic As Shape
Dim tempChartObj As ChartObject
Dim savePath As String

Set myPic = ActiveSheet.Shapes("Picture 1")
Set tempChartObj = ActiveSheet.ChartObjects.Add(0, 0, myPic.Width, myPic.Height)
savePath = "C:\Users\marks\Downloads\mySavedPic.jpg"

'Copy picture into chart, then export chart
myPic.Copy

tempChartObj.Chart.ChartArea.Select
tempChartObj.Chart.Paste
tempChartObj.Chart.Export savePath
tempChartObj.Delete

End Sub

Conclusion

In this post we have provided over 25 examples to demonstrate how to insert, delete, move and control pictures with VBA. Checkout the other posts on this site which use these techniques:


Discover how you can automate your work with our Excel courses and tools.

Excel Academy

Excel Academy
The complete program for saving time by automating Excel.

Excel Automation Secrets

Excel Automation Secrets
Discover the 7-step framework for automating Excel.

Office Scripts Course

Office Scripts: Automate Excel Everywhere
Start using Office Scripts and Power Automate to automate Excel in new ways.

2 thoughts on “How to Insert, Move & Delete Pictures with VBA”

  1. In a rather complex XLS project, I’m creating a Shapes.AddPicture object. However, I want to test if it exists at one point (XLS seems to want to drop it for no particular reason).
    (Set PlanePic = ws.Shapes.AddPicture(i, msoCTrue, msoCTrue, shLeft, shTop, shWidth, shHeight))
    If (PlanePic = True) doesn’t work.
    Ideas?

    Reply

Leave a Comment