はじめに
会社ではサブスクリプション型の Office365,自宅では買い切り型の Office 2019(最近 2024 が出たが)を使用している方も多いのではないでしょうか?Office365 のほうはいつの間にか Excel に便利なセル関数が追加されていたりなど,サブスクリプションサービスならではの日々進歩を感じることがありますが,大半の機能は代替手段で置き換えることができるので,Office 2019 に不満がある訳ではありませんでした。
ところが,Office365 で新しく追加された「画像の透明度を調整する機能」がとても便利なのです。残念ながら,これに相当する機能は Office2019 には見当たりません。
Office365 の PowerPoint |
Office2019 の PowerPoint |
---|
ところが Office365 で半透明化した画像は Office2019 でも半透明に見えるので,Office のファイルフォーマット自体は半透明化の属性をサポートしており,それを調整する機能を Office2019 は持たないだけなのでしょう。であれば,画像の透明度を調整する機能を VBA マクロかアドインで作ればよいのではないか?と考えたのです。
Shape オブジェクトのどの属性なのか?
Office365 にて PowerPoint のプレゼンテーションを新規作成し,Qiita のアイコン画像を二つ貼り付けました。このうち左側は透明度50%としました。また両者の区別がつき易いように左側の画像(透明度50%のほう)の代替テキストを「図1」と名付け,もう一方は「図2」としました。
次にアクティブプレゼンテーションにおいて,現在選択している図形の属性を表示するスクリプトを PowerShell で作成しました。
Set-PSDebug -Strict
[Reflection.Assembly]::LoadWithPartialName("Office") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.PowerPoint") | Out-Null
#-------------------------------------------------------------------------------
# PowerPoint を起動する
#-------------------------------------------------------------------------------
$app = New-Object -ComObject PowerPoint.Application
$app.Visible = [Microsoft.Office.Core.MsoTriState]::msoTrue
#-------------------------------------------------------------------------------
# アクティブプレゼンテーションを返す
#-------------------------------------------------------------------------------
if($app.Presentations.Count -lt 1) {
Write-Host "アクティブプレゼンテーションがありません!!"
Exit -1
}
$ppt = $app.ActivePresentation
#-------------------------------------------------------------------------------
# 現在選択している図形コレクションを取得する
#-------------------------------------------------------------------------------
$ppSelectionShapes = [Microsoft.Office.Interop.PowerPoint.PpSelectionType]::ppSelectionShapes
if($app.ActiveWindow.Selection.Type -ne $ppSelectionShapes) {
Write-Host "現在,選択している図形がありません!!"
Exit -1
}
#-------------------------------------------------------------------------------
# 現在選択している図形に対して属性を表示する
#-------------------------------------------------------------------------------
foreach($shape in $app.ActiveWindow.Selection.ShapeRange) {
Write-Host "Name:",
$shape.Name
Write-Host "Type:",
$shape.Type
Write-Host "AlternativeText:",
$shape.AlternativeText
Write-Host "Fill.Type:",
$shape.Fill.Type
Write-Host "Fill.Transparency:",
$shape.Fill.Transparency
Write-Host "Fill.PictureEffects.Count:",
$shape.Fill.PictureEffects.Count
Write-Host "PictureFormat.TransparencyColor:",
$shape.PictureFormat.TransparencyColor
Write-Host "PictureFormat.TransparentBackground:",
$shape.PictureFormat.TransparentBackground
Write-Host ""
}
スクリプトの実行結果を以下に示しますが,それっぽい属性(プロパティ)を調べても透明度を設定していないことが分かります。困りました・・・一体,どこで透明度を設定しているのでしょうか?
c:\qiita>shapeinfo.ps1
Name: Picture 1
Type: 13
AlternativeText: 図1
Fill.Type: -2
Fill.Transparency: 1
Fill.PictureEffects.Count: 0
PictureFormat.TranparencyColor: -2147483648
PictureFormat.TranparentBackground: -1
Name: Picture 2
Type: 13
AlternativeText: 図2
Fill.Type: -2
Fill.Transparency: 1
Fill.PictureEffects.Count: 0
PictureFormat.TranparencyColor: -2147483648
PictureFormat.TranparentBackground: -1
Shape オブジェクトに隠し属性はないか?
Microsoft の公式サイトより Shape オブジェクト (PowerPoint) - microsft を見ても,Shape オブジェクトにそれらしい属性は見当たらないのです。もしかしたら,非公開の隠し属性があるのではないでしょうか?ということで Shape オブジェクトの全てのメンバー(メソッド,プロパティ)を表示するスクリプトを書いてみました。
Set-PSDebug -Strict
[Reflection.Assembly]::LoadWithPartialName("Office") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.PowerPoint") | Out-Null
#-------------------------------------------------------------------------------
# PowerPoint を起動する
#-------------------------------------------------------------------------------
$app = New-Object -ComObject PowerPoint.Application
$app.Visible = [Microsoft.Office.Core.MsoTriState]::msoTrue
#-------------------------------------------------------------------------------
# アクティブプレゼンテーションを返す
#-------------------------------------------------------------------------------
if($app.Presentations.Count -lt 1) {
Write-Host "アクティブプレゼンテーションがありません!!"
Exit -1
}
$ppt = $app.ActivePresentation
#-------------------------------------------------------------------------------
# 現在選択している図形コレクションを取得する
#-------------------------------------------------------------------------------
$ppSelectionShapes = [Microsoft.Office.Interop.PowerPoint.PpSelectionType]::ppSelectionShapes
if($app.ActiveWindow.Selection.Type -ne $ppSelectionShapes) {
Write-Host "現在,選択している図形がありません!!"
Exit -1
}
#-------------------------------------------------------------------------------
# 現在選択している図形に対して属性を表示する
#-------------------------------------------------------------------------------
foreach($shape in $app.ActiveWindow.Selection.ShapeRange) {
$shape | Get-Member
}
Microsoft のサイト情報と PowerShell スクリプトの出力を比較します。この結果を見ると,Microsoft のサイトにすべてのプロパティが掲載されている訳ではなく,いくつかのプロパティは漏れていました。なお,PowerShell スクリプトの出力は Office365 と Office2019 で全く同一でしたが,Office2016 および Office2010 では欠けているプロパティがいくつか散見されます。しかし,Office2010 ですら半透明に見えるので,Office 2010 にも共通して存在するプロパティの中に透明度の属性があるはずなのです。
プロパティ | Microsoft サイト 情報 |
PowerShell 出力 | |||
---|---|---|---|---|---|
Office 365 |
Office 2019 |
Office 2016 |
Office 2010 |
||
Adjustments | ○ | ○ | ○ | ○ | ○ |
AlternativeText | ○ | ○ | ○ | ○ | ○ |
AnimationSettings | ○ | ○ | ○ | ○ | ○ |
Application | ○ | ○ | ○ | ○ | ○ |
AutoShapeType | ○ | ○ | ○ | ○ | ○ |
BackgroundStyle | ○ | ○ | ○ | ○ | ○ |
BlackWhiteMode | ○ | ○ | ○ | ○ | ○ |
Callout | ○ | ○ | ○ | ○ | ○ |
CanvasItems | × | ○ | ○ | ○ | ○ |
Chart | ○ | ○ | ○ | ○ | ○ |
Child | ○ | ○ | ○ | ○ | ○ |
ConnectionSiteCount | ○ | ○ | ○ | ○ | ○ |
Connector | ○ | ○ | ○ | ○ | ○ |
ConnectorFormat | ○ | ○ | ○ | ○ | ○ |
Creator | ○ | ○ | ○ | ○ | ○ |
CustomerData | ○ | ○ | ○ | ○ | ○ |
Decorative | ○ | ○ | ○ | × | × |
Diagram | × | ○ | ○ | ○ | ○ |
DiagramNode | × | ○ | ○ | ○ | ○ |
Fill | ○ | ○ | ○ | ○ | ○ |
Glow | ○ | ○ | ○ | ○ | ○ |
GraphicStyle | ○ | ○ | ○ | × | × |
GroupItems | ○ | ○ | ○ | ○ | ○ |
HasChart | ○ | ○ | ○ | ○ | ○ |
HasDiagram | × | ○ | ○ | ○ | ○ |
HasDiagramNode | × | ○ | ○ | ○ | ○ |
HasInkXML | ○ | ○ | ○ | ○ | × |
HasSectionZoom | × | ○ | ○ | × | × |
HasSmartArt | ○ | ○ | ○ | ○ | ○ |
HasTable | ○ | ○ | ○ | ○ | ○ |
HasTextFrame | ○ | ○ | ○ | ○ | ○ |
Height | ○ | ○ | ○ | ○ | ○ |
HorizontalFlip | ○ | ○ | ○ | ○ | ○ |
Id | ○ | ○ | ○ | ○ | ○ |
InkXML | ○ | ○ | ○ | ○ | × |
IsNarration | ○ | ○ | ○ | ○ | × |
Left | ○ | ○ | ○ | ○ | ○ |
Line | ○ | ○ | ○ | ○ | ○ |
LinkFormat | ○ | ○ | ○ | ○ | ○ |
LockAspectRatio | ○ | ○ | ○ | ○ | ○ |
Locked | × | ○ | ○ | × | × |
MediaFormat | ○ | ○ | ○ | ○ | ○ |
MediaType | ○ | ○ | ○ | ○ | ○ |
Model3D | ○ | ○ | ○ | × | × |
Name | ○ | ○ | ○ | ○ | ○ |
Nodes | ○ | ○ | ○ | ○ | ○ |
OLEFormat | ○ | ○ | ○ | ○ | ○ |
Parent | ○ | ○ | ○ | ○ | ○ |
ParentGroup | ○ | ○ | ○ | ○ | ○ |
PictureFormat | ○ | ○ | ○ | ○ | ○ |
PlaceholderFormat | ○ | ○ | ○ | ○ | ○ |
Reflection | ○ | ○ | ○ | ○ | ○ |
Rotation | ○ | ○ | ○ | ○ | ○ |
RTF | × | ○ | ○ | ○ | ○ |
Script | × | ○ | ○ | ○ | ○ |
Shadow | ○ | ○ | ○ | ○ | ○ |
ShapeStyle | ○ | ○ | ○ | ○ | ○ |
SmartArt | ○ | ○ | ○ | ○ | ○ |
SoftEdge | ○ | ○ | ○ | ○ | ○ |
SoundFormat | × | ○ | ○ | ○ | ○ |
Table | ○ | ○ | ○ | ○ | ○ |
Tags | ○ | ○ | ○ | ○ | ○ |
TextEffect | ○ | ○ | ○ | ○ | ○ |
TextFrame | ○ | ○ | ○ | ○ | ○ |
TextFrame2 | ○ | ○ | ○ | ○ | ○ |
ThreeD | ○ | ○ | ○ | ○ | ○ |
Title | ○ | ○ | ○ | ○ | ○ |
Top | ○ | ○ | ○ | ○ | ○ |
Type | ○ | ○ | ○ | ○ | ○ |
VerticalFlip | ○ | ○ | ○ | ○ | ○ |
Vertices | ○ | ○ | ○ | ○ | ○ |
Visible | ○ | ○ | ○ | ○ | ○ |
Width | ○ | ○ | ○ | ○ | ○ |
ZOrderPosition | ○ | ○ | ○ | ○ | ○ |
XML ファイルの差分をとってみる
Office365 で画像の透明度を変更したファイルを Office2019 で開いても(Office2010 でも)半透明に見えるので,ファイルに属性が残されているのは確かです。幸いなことに最近の Microsoft Office のファイル形式は Office Open XML といって ZIP 圧縮された XML 形式のテキストファイルなので頑張れば読めます。
ということで以下は Office2019 と Office365 で ppt\slides\slide1.xml
の差分を取った結果です。なお,差分を取る前に見易いように XML を整形しています。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
<p:cSld>
<p:spTree>
<p:nvGrpSpPr>
<p:cNvPr id="1" name="" />
<p:cNvGrpSpPr />
<p:nvPr />
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="0" y="0" />
<a:ext cx="0" cy="0" />
<a:chOff x="0" y="0" />
<a:chExt cx="0" cy="0" />
</a:xfrm>
</p:grpSpPr>
<!-- 左側の画像 -->
<p:pic>
<p:nvPicPr>
<p:cNvPr id="2" name="図 1" descr="図1">
<a:extLst>
<a:ext uri="{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}">
<a16:creationId
xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main"
id="{79D6EA02-E6FB-BB88-E74E-D2F454248485}" />
</a:ext>
</a:extLst>
</p:cNvPr>
<p:cNvPicPr>
<a:picLocks noChangeAspect="1" />
</p:cNvPicPr>
<p:nvPr />
</p:nvPicPr>
<p:blipFill>
<a:blip r:embed="rId2">
+ <a:alphaModFix amt="50000" />
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi
xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main"
val="0" />
</a:ext>
</a:extLst>
</a:blip>
<a:stretch>
<a:fillRect />
</a:stretch>
</p:blipFill>
<p:spPr>
<a:xfrm>
<a:off x="4267200" y="2514600" />
<a:ext cx="1714500" cy="1714500" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</p:spPr>
</p:pic>
<!-- 右側の画像 -->
<p:pic>
<p:nvPicPr>
<p:cNvPr id="3" name="図 2" descr="図2">
<a:extLst>
<a:ext uri="{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}">
<a16:creationId
xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main"
id="{AC18B259-1E4D-D00B-F06C-2D4B7B5EF901}" />
</a:ext>
</a:extLst>
</p:cNvPr>
<p:cNvPicPr>
<a:picLocks noChangeAspect="1" />
</p:cNvPicPr>
<p:nvPr />
</p:nvPicPr>
<p:blipFill>
<a:blip r:embed="rId2">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi
xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main"
val="0" />
</a:ext>
</a:extLst>
</a:blip>
<a:stretch>
<a:fillRect />
</a:stretch>
</p:blipFill>
<p:spPr>
<a:xfrm>
<a:off x="6553200" y="2514600" />
<a:ext cx="1714500" cy="1714500" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</p:spPr>
</p:pic>
</p:spTree>
<p:extLst>
<p:ext uri="{BB962C8B-B14F-4D97-AF65-F5344CB8AC3E}">
<p14:creationId
xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"
val="947211181" />
</p:ext>
</p:extLst>
</p:cSld>
<p:clrMapOvr>
<a:masterClrMapping />
</p:clrMapOvr>
</p:sld>
ということで,ようやく見つけました。<a:alphaModFix amt="50000" />
というタグですね。透明度をパーセント(百分率)として,その 1000 倍の数値を与えるようです。
AlphaModulationFixed Class (DocumentFormat.OpenXml v3.0.1) - Microsoft
ただし,この属性を VBA あるいは VBScript, または PowerShell で変更できる方法はまだ分かっていません。どうしても変更したければ,PowerPoint のファイルの拡張子を *.zip
に変更してから ZIP ファイルを展開して,上記の XML ファイルをテキストエディタで直接書き換え,再び ZIP ファイルに圧縮して拡張子を *.pptx
に戻す方法ですが,自分も含めて誰もやらない(やりたがらない)ですね。
この件については引き続き調査中です。進展があり次第,後日,続報記事を書きたいと思います。