How do I determine the image dimensions of a tiff file? - vbscript

I have a vbscript script and I need to chew through a directory of .tif files. For each file, I need to determine if the file is proportioned as a landscape or a portrait. Basically, I need to be able to get the image dimensions for each file. So for, I have seen some examples of people reading the file file headers to extract this sort of information from jpg or bmp files. Has anyone done the same thing to extract the dimensions for a tiff file?

In VBScript, you can determine the image dimensions in two ways:
Using the WIA Automation Library (download link, MSDN documentation, an excellent Hey, Scripitng Guy! article on the subject). Once you have the wiaaut.dll library registered, you can use the following simple code:
Set oImage = CreateObject("WIA.ImageFile")
oImage.LoadFile "C:\Images\MyImage.tif"
WScript.Echo "Width: " & oImage.Width & vbNewLine & _
"Height: " & oImage.Height
Using the GetDetailsOf method to read the corresponding extended file properties. This is a native Windows scripting method, so no external libraries are required; but the code is longer:
Const DIMENSIONS = 31
CONST WIDTH = 162
CONST HEIGTH = 164
Set oShell = CreateObject ("Shell.Application")
Set oFolder = oShell.Namespace ("C:\Images")
Set oFile = oFolder.ParseName("MyImage.tif")
strDimensions = oFolder.GetDetailsOf(oFile, DIMENSIONS)
strWidth = oFolder.GetDetailsOf(oFile, WIDTH)
strHeigth = oFolder.GetDetailsOf(oFile, HEIGTH)
WScript.Echo "Dimensions: " & strDimensions & vbNewLine & _
"Width: " & strWidth & vbNewLine & _
"Height: " & strHeigth
This script outputs something like:
Dimensions: 2464 x 3248
Width: 2464 pixels
Height: 3248 pixels
so if you need plain numbers, you'll have to extract them from the returned strings.
There's also another problem with this method - the property indexes (those constants in the beginning on the script) are different in different Windows versions, as I explained in this answer. The above script is for Windows 7, but if you use another Windows versions or if you want the script to work on different Windows versions, you'll need to use version-specific indexes. The most complete list of available property indexes is here.

I would recommend using Atalasoft's DotImage Photo Its powerful & it's free! But, it's a .NET package, so you'll have do some Regasm Magic to make it work. Go check out Use vb.net in VBScript before you get started.
Here is the code you'll need to get the dimensions.
Public Function GetHeight(path As String) As Integer
Using stm As New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
Dim decoder As New TiffDecoder()
If Not decoder.IsValidFormat(stm) Then
Throw New Exception("not a TIFF")
End If
Dim image As AtalaImage = decoder.Read(stm, Nothing)
Return image.Height
' Return image.Width --- To return the Width.
End Using
End Function

Related

VBA download and embed images using url from adjacent cell

I've attempted the solution in the following.
Inserting an Online Picture to Excel with VBA
Unfortunately I get a run-time error '1004'
"Unable to get the Insert property of the Picture class"
which stops on the following code :
Set myPicture = ActiveSheet.Pictures.Insert(pic)
Could this be due to my Office version 2016 (64bit) ?
If not, are there any suggestions of how I might get embed images to adjacent cells in column AK using the image urls from column AJ ?
Thanks in advance
There's some evidence that Excel has trouble downloading from AWS, and I've recreated your issue using the URL you mentioned. In this case, if I were on a deadline I'd put in this fall-back method when the first one fails: download the file, then insert it into the document, then delete the file.
directDownloadFailed:
Dim FileNum As Long
Dim TempFile As String
Dim FileData() As Byte
Dim WHTTP As Object
Set WHTTP = CreateObject("WinHTTP.WinHTTPrequest.5.1")
WHTTP.Open "GET", imgURL, False
WHTTP.Send
FileData = WHTTP.ResponseBody
Set WHTTP = Nothing
FileNum = FreeFile
TempFile = "path\to\save\img.jpg"
Open TempFile For Binary Access Write As #FileNum
Put #FileNum, 1, FileData
Close #FileNum
Set img = ActiveSheet.Pictures.Insert(TempFile)
SetAttr TempFile, vbNormal
Kill TempFile
GoTo resumeProcessingImg
#keydemographic
I appreciate the response and that definitely sounds like an option but I cannot get that code to work or incorporate it into the code I'm using. I get a compile error "Label Not defined" on GoTo resumeProcessingImg
The following will download and embed the images into the cells but the code stops once it gets to the s3 aws image urls.
I'll try a few other ways to incorporate your code but I'm not having much luck with it so far.
This is my test file
Sub URL2IMG()
Dim pic As String 'path of pic
Dim myPicture As Picture 'embedded pic
Dim rng As Range 'range over which we will iterate
Dim cl As Range 'iterator
Set rng = Range("b2:b12") '<~~ as needed, Modify range to where the images are to be embedded.
For Each cl In rng
pic = cl.Offset(0, -1) '<~~ defines image link URL in column to the left of the embedded column
Set myPicture = ActiveSheet.Pictures.Insert(pic)
'you can play with the following to manipulate the size & position of the picture.
With myPicture
.ShapeRange.LockAspectRatio = msoFalse
' currently this shrinks the picture to fit inside the cell.
.Width = cl.Width
.Height = cl.Height
.Top = Rows(cl.Row).Top
.Left = Columns(cl.Column).Left
End With
Next
End Sub

Decompose lines of standard powerpoint shape

I would like to split a standard PowerPoint shape into separate lines so that I can have full control over how and when they appear when using animations. Thus, I would like to see that the shape on top (a standard PowerPoint shape) is decomposed in the one below (without the space betwen the lines.
I hope somebody has some creative ideas.
This may help get started. Look up the docs on the various properties/methods for more information.
Sub thing()
Dim oSh As Shape
Dim x As Long
Dim pointsArray()
Set oSh = ActiveWindow.Selection.ShapeRange(1)
With oSh
Debug.Print .Nodes.Count
With .Nodes
For x = 1 To .Count
Debug.Print "X = " & .Item(x).Points(1, 1)
Debug.Print "Y = " & .Item(x).Points(1, 2)
Next
End With
End With
End Sub

Is there a way to read images from a folder and save it in powerpoint

I have approx. 100 images , I want to read those images, do the resizing and save it in a power point using matlab, Is it way to save those images in a power point giving title to each slide.
I am reading images using this code:
for i = 1:numel(pngfiles)
im{i} = imread(pngfiles{i});
imrgb{i} = rgb2gray(im{i});
imrgb_z{i} = imrgb{i}(160:350,280:450);
end
It seems to me that the best approach would be to use a VBA script inside Powerpoint, rather than manipulating ppt from Matlab. The steps would be
Create your list of images in a folder - using a sensible naming scheme
Open Powerpoint; go to the VBA editor (Alt-F11) and add a module with the following lines of code in it (note - this is taken straight from https://stackoverflow.com/a/5038907/1967396 with minimal edits):
-
Sub CreatePictureSlideshow( )
Dim presentation
Dim layout
Dim slide
Dim FSO
Dim folder
Dim file
Dim folderName
Dim fileType
' Set this to point at the folder you wish to import JPGs from
' Note: make sure this ends with a backslash \
fileType = ".jpg" ' <<< change this to the type you want
folderName = "c:\somedirectory\" ' <<< change this to the directory you want
' setup variables
Set presentation = Application.ActivePresentation
' choose the layout you want: e.g. if the title needs a particular format
Set layout = Application.ActivePresentation.SlideMaster.CustomLayouts(1)
Set FSO = CreateObject("Scripting.FileSystemObject")
' Retrieve the folder's file listing and process each file
Set folder = FSO.GetFolder(folderName)
For Each file In folder.Files
' Filter to only process JPG images
If LCase(Right(file.Name), 4)) = fileType Then
' Create the new slide and delete any pre-existing contents
Set slide = presentation.Slides.AddSlide(presentation.Slides.count + 1, layout)
While slide.Shapes.count > 0
slide.Shapes(1).Delete ' <<< You might not want to do this is you want to keep the title placeholder
Wend
' Add the picture
slide.Shapes.AddPicture folderName + file.Name, False, True, 10, 10
' Optional: create a textbox with the filename on the slide for reference
' alternatively, add text to the title shape
Dim textBox
Set textBox = slide.Shapes.AddTextbox(msoTextOrientationHorizontal, 10, 10, 200, 200)
textBox.TextFrame.TextRange.Text = file.Name ' <<< or whatever "title" you wanted
End If
Next
End Sub
You can modify this further to get the title in the format you want, etc.
you could try this:
Is there an example of using MATLAB to create PowerPoint slides?
For example:
% before the following, you have to create the ppt as explained, see link above!
% I prefer using some name instead of i or j
for img_ind = 1:numel(pngfiles)
% this depends on the ppt-version (see link above)-> here for 2007 and higher
mySlide = Presentation.Slides.Add(1,'ppLayoutBlank')
% Note: Change the image file full path names to where you save them
Image1 = mySlide.Shapes.AddPicture('<full path>\name_of_image(img_ind).png','msoFalse','msoTrue',100,20,500,500)
end
% then you have to save it, see link above!
In your case, I guess you have to save the image first as shown in the example:
print('-dpng','-r150','<full path>\test1.png')
edit
This will only work when using Matlab on Windows, because COM is needed. See comments on Floris answer!
Coming late to this party: Here's a "Matlab Pick of the Week" tool:
http://www.mathworks.com/matlabcentral/fileexchange/30124-smart-powerpoint-exporter
Take note of some of the comments at that page, as apparently the tool has not been updated in a few years.

REALBasic - Programmatically create controls

i'm tring to create some label programmatically, the code doesn't return any error but i cannot see any label in my window.
dim dr As DatabaseRecord
dim sql As String
sql = "SELECT * FROM pack WHERE applicabilita_modello LIKE '%" + versione + "%'"
dim rs As RecordSet = database.SQLSelect(sql)
dim i As Integer = 1
dim test(10) As Label
while not rs.EOF
test(i) = new Label
test(i).Text = rs.Field("descrizione").StringValue
test(i).Left = me.Left
test(i).Top = me.Top * i
test(i).Enabled = true
test(i).Visible = true
rs.MoveNext
i = i + 1
wend
rs.Close
i've verified that the recordset contain some data, the loop work correctly but no label is shown and cannot understand why.
thanks for any help
There are two ways to create controls at runtime in Real Studio. The first is to create a control array. You could name the control MyLabel and give it an index of zero. Then your code would be:
test(i) = new MyLabel
The second is to use a ContainerControl. This container would contain a label and because you can add them to your window (or other container) using the NEW command and using the ContainerControl.EmbedWithin method.
I generally prefer the ContainerControl approach for many reasons, but mostly because control arrays make the logic a big more convoluted. The only drawback with containers is that it requires Real Studio Professional or Real Studio Enterprise.
http://docs.realsoftware.com/index.php/UsersGuide:Chapter_5:Creating_New_Instances_of_Controls_On_The_Fly
http://docs.realsoftware.com/index.php/ContainerControl

Is there an Alternative to using the LoadPicture("bmp_or_icon_file_path") to loading Images in Excel 2007 VBA

I have an Excel 2007 Worksheet with many buttons and labels that act as menu options (i.e. user clicks the buttons, labels with images) and is presented with forms, or some thing else.
These images / icons for the buttons and labels are loaded in VBA by assigning the Picture property of the Control and calling LoadPicture() method with the full image file path as parameter, like So.
With SomeFormObject
.cmdOpenFile.Picture = LoadPicture("F:\projectname\images\fileopen.BMP")
End With
This method of loading images for buttons, other controls is causing 2 issues.
1) It creates a dependency on the image files and physical location for every user, so if a user does not have the drive mapped and files present, the VBA fails with runtime error of file or path not found.
2)
The app gets very slow if the images are on a shared drive (which is the case)
I want to eliminate both issues and somehow load icons, images into control internally, without any external dependencies on external image files.
What is the best way to achieve this in Excel 2007 VBA?
I could not file any Visual Basic 6.0 / Visual Studio style "Resource File Editor" / feature with which to accomplish this.
Please advice! thank you
-Shiva #
mycodetrip.com
I really hope that there is a easier way to do this, but this is the only one I found:
The Idea is:
You keep the Pictures embedded in a Sheet and every time you want to set the pictures for the Command you export them from your worksheet to a file and load them through LoadPicture. The only way to export an embedded Picture through VBA that I found is by making it a Chart first.
The following code is based on 'Export pictures from Excel' from johnske
Option Explicit
Sub setAllPictures()
setPicture "Picture 18", "CommandButtonOpen"
setPicture "Picture 3", "CommandButtonClose"
End Sub
Sub setPicture(pictureName As String, commandName As String)
Dim pictureSheet As Worksheet
Dim targetSheet As Worksheet
Dim embeddedPicture As Picture
Dim pictureChart As Chart
Dim MyPicture As String
Dim PicWidth As Long
Dim PicHeight As Long
Set pictureSheet = Sheets("NameOfYourPictureSheet") ' <- to Change '
Set targetSheet = Sheets("NameOfYourSheet") ' <- to Change '
Set embeddedPicture = pictureSheet.Shapes(pictureName).OLEFormat.Object
With embeddedPicture
MyPicture = .Name
PicHeight = .ShapeRange.Height
PicWidth = .ShapeRange.Width
End With
Charts.Add
ActiveChart.Location Where:=xlLocationAsObject, Name:=pictureSheet.Name
Set pictureChart = ActiveChart
embeddedPicture.Border.LineStyle = 0
With pictureChart.Parent
.Width = PicWidth
.Height = PicHeight
End With
With pictureSheet
.Select
.Shapes(MyPicture).Copy
With pictureChart
.ChartArea.Select
.Paste
End With
.ChartObjects(1).Chart.Export Filename:="temp.jpg", FilterName:="jpg"
End With
pictureChart.Parent.Delete
Application.ScreenUpdating = True
targetSheet.Shapes(commandName).OLEFormat.Object.Object.Picture = LoadPicture("temp.jpg")
Set pictureChart = Nothing
Set embeddedPicture = Nothing
Set targetSheet = Nothing
Set pictureSheet = Nothing
End Sub
Sub listPictures()
' Helper Function to get the Names of the Picture-Shapes '
Dim pictureSheet As Worksheet
Dim sheetShape As Shape
Set pictureSheet = Sheets("NameOfYourSheet")
For Each sheetShape In pictureSheet.Shapes
If Left(sheetShape.Name, 7) = "Picture" Then Debug.Print sheetShape.Name
Next sheetShape
Set sheetShape = Nothing
Set pictureSheet = Nothing
End Sub
To Conclude:
Loading the Images from a Mapped Networked Drive seems less messy, and there shouldn't be that much of a speed difference.
2 alternatives i can think of: form.img.picture=pastepicture , and = oleobjects("ActiveXPictureName").object.picture.

Resources