2024年3月3日日曜日

Google Nik Collection を GIMP から - Win11 限定

恐らく、使ってる方は いない! と思う訳ですが、
大昔の Google Nik の 実行ファイル を GIMP から動かす奴。
Windows 10 では動いていましたが、
独自に組み込んだ MS Paint が Windows 11 でエラーを吐く事への対応です。


新規に導入しようとしても、
Google Nik (正式には Google Nik Collection) は、
既に Google の元を離れ、別会社保有となり、有償化されていますね。
昔ので良いから動かしたい! と言う方の為に書きます。
尚且つ、既に、昔の Installer をお持ちの方限定! ですが。

投稿 Google Nik Collection を GIMP から  で書いた様に、
Windows 10 では動いていたのですが、
Windoww 11 は MS Paint 実行ファイルの場所が変わっています。
無論、旧 Google Nik の 実行ファイル は標準導入の場合、
同じ場所にありますが、
MS Paint (mspaint.exe) の場所が違うのです。

  詳細は、
  Win11 mspaint.exe よ、何処?   を参照下さい。

該当 Script から、MS Paint を外していれば、
不具合は起こりませんが、
MS Paint 項目を選ぶと 落とされて仕舞います。
無いものを呼び出すのですから、
当たり前と言えば当たり前。

精神衛生上宜しく無い ので、直しました。
無論、Windows 11 専用の GIMP Python Script になります。

  本来なら、
  実行ファイル有無を確認して、エラー処理するべきですが、 GIMP 2.10 も余命は短そうですし、
  旧 Google Nik も、新たに入手は困難でしょうから、
  エラー処理未完のまま、動く様にしただけ! です。

  各種実行ファイルが既に揃っている前提 になりますね。

  更に、命名の中に Win11 の文字を入れた方が良いとも思うのですが、
  バックアップして、単にファイル名を弄っただけだと動きませんから、
  其の辺りは Python を或る程度分かっている方 にお任せしましょう。

尚、
OS の種別を自動判断して分岐するのが好ましい気もしますが、
其処迄、手を掛けるのもどうかな?、なので、端折ります。

  VB.net,C#,Python でも、
  Windows 10 の Version は 10.0.19045 (2024/02/10)、
  Windows 11 の Version は 10.0.22621 (22xxx 以上) が返ります。
    Python なら platform.version() 。
  将来、Windows 12 (?) が誕生すると、どうなるのか?、
  なので、 触らぬ神に祟り無し にします。


手直しされる方は 前投稿  をご覧下さい。
Win10 の部分1行 を Win11 の複数行に置換します。
  修正箇所を 赤字 表記。
  
  注: GIMP 2.10 専用。  2.99.x や 3.x では動きません。
修正後の 全 Code を掲載しますね。  x64 Case 。

#!/usr/bin/env python

'''
ShellOut.py
call an external program passing the active layer as a temp file.  Windows Only(?)

Author:
Rob Antonishen

Version:
0.7 fixed file save bug where all files were png regardless of extension
0.6 modified to allow for a returned layer that is a different size
   than the saved layer for
  0.5 file extension parameter in program list.
0.4 modified to support many optional programs.

this script is modelled after the mm extern LabCurves trace plugin
by Michael Munzert http://www.mm-log.com/lab-curves-gimp

and thanks to the folds at gimp-chat has grown a bit ;)

License:

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 3 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

The GNU Public License is available at
http://www.gnu.org/copyleft/gpl.html

'''


'''
Start Edit by ShiroYuki_Mot
Points
Change Program Name Starts With "Nik ".
Change File Extention From jpg To png.
Add Program MS Paint.
Change LayerName  From "Visible" or OldName  To Add " > Ext.: + AppName"
Modified 2017/02/21
Change for ms-paint.exe on Windows 11
Modified 2024/02/08
'''


from gimpfu import *
import shlex
import subprocess
import os, sys
import tempfile

#program list function (globals are evil)
def listcommands(option=None):
  #
  # Insert additonal shell command into this list.  They will show up in the drop menu in this order.
  # Use the syntax:
  # ["Menu Label", "command", "ext"]
  #
  # Where what gets executed is command fileame so include and flags needed in the command.
  #
  # For Windows 11
  import getpass
  username = getpass.getuser()
  programlist = [
  ["MS Paint", "¥"C:¥¥Users¥¥" + username + "¥¥AppData¥¥Local¥¥Microsoft¥¥WindowsApps¥¥mspaint.exe¥"", "bmp"],
  ["Nik DFine 2", "¥"C:¥¥Program Files¥¥Google¥¥Nik Collection¥¥Dfine 2¥¥Dfine 2 (64-Bit)¥¥Dfine2.exe¥"", "png"],
  ["Nik Sharpener Pro 3", "¥"C:¥¥Program Files¥¥Google¥¥Nik Collection¥¥Sharpener Pro 3¥¥Sharpener Pro 3 (64-Bit)¥¥SHP3OS.exe¥"", "png"],
  ["Nik Viveza 2", "¥"C:¥¥Program Files¥¥Google¥¥Nik Collection¥¥Viveza 2¥¥Viveza 2 (64-Bit)¥¥Viveza 2.exe¥"", "png"],
  ["Nik Color Efex Pro 4", "¥"C:¥¥Program Files¥¥Google¥¥Nik Collection¥¥Color Efex Pro 4¥¥Color Efex Pro 4 (64-Bit)¥¥Color Efex Pro 4.exe¥"", "png"],
  ["Nik Analog Efex Pro 2", "¥"C:¥¥Program Files¥¥Google¥¥Nik Collection¥¥Analog Efex Pro 2¥¥Analog Efex Pro 2 (64-Bit)¥¥Analog Efex Pro 2.exe¥"", "png"],
  ["Nik HDR Efex Pro 2", "¥"C:¥¥Program Files¥¥Google¥¥Nik Collection¥¥HDR Efex Pro 2¥¥HDR Efex Pro 2 (64-Bit)¥¥HDR Efex Pro 2.exe¥"", "png"],
  ["Nik Silver Efex Pro 2", "¥"C:¥¥Program Files¥¥Google¥¥Nik Collection¥¥Silver Efex Pro 2¥¥Silver Efex Pro 2 (64-Bit)¥¥Silver Efex Pro 2.exe¥"", "png"],
  ["","",""]
  ]
  
  if option == None: # no parameter return menu list, otherwise return the appropaiate array
    menulist = []
    for i in programlist:
      if i[0] != "":
        menulist.append(i[0])
    return menulist
  else:
    return programlist[option]


def plugin_main(image, drawable, visible, command):
  pdb.gimp_image_undo_group_start(image)
  
  # Copy so the save operations doesn't affect the original
  if visible == 0:
    # Save in temporary.  Note: empty user entered file name
    temp = pdb.gimp_image_get_active_drawable(image)
  else:
    # Get the current visible
    temp = pdb.gimp_layer_new_from_visible(image, image, "Visible")
    image.add_layer(temp, 0)

  buffer = pdb.gimp_edit_named_copy(temp, "ShellOutTemp")

  #save selection if one exists
  hassel = pdb.gimp_selection_is_empty(image) == 0
  if hassel:
    savedsel = pdb.gimp_selection_save(image)

  tempimage = pdb.gimp_edit_named_paste_as_new(buffer)
  pdb.gimp_buffer_delete(buffer)
  if not tempimage:
    raise RuntimeError
  pdb.gimp_image_undo_disable(tempimage)

  tempdrawable = pdb.gimp_image_get_active_layer(tempimage)
  
  #get the program to run and filetype.
  progtorun = listcommands(command)
  
  # Use temp file names from gimp, it reflects the user's choices in gimp.rc
  # change as indicated if you always want to use the same temp file name
  # tempfilename = pdb.gimp_temp_name(progtorun[2])
  tempfilename = os.path.join(tempfile.gettempdir(), "ShellOutTempFile."+progtorun[2])
  

  # !!! Note no run-mode first parameter, and user entered filename is empty string
  pdb.gimp_progress_set_text ("Saving a copy")
  pdb.gimp_file_save(tempimage, tempdrawable, tempfilename, tempfilename)

  # Build command line call
  command = progtorun[1] + " ¥"" + tempfilename + "¥""
  args = shlex.split(command)

  # Invoke external command
  pdb.gimp_progress_set_text ("calling " + progtorun[0] + "...")
  pdb.gimp_progress_pulse()
  child = subprocess.Popen(args, shell=False)
  child.communicate()

  # put it as a new layer in the opened image
  try:
    newlayer2 = pdb.gimp_file_load_layer(tempimage, tempfilename)
  except:
    RuntimeError

  tempimage.add_layer(newlayer2,-1)
  buffer = pdb.gimp_edit_named_copy(newlayer2, "ShellOutTemp")

  if visible == 0:
    drawable.resize(newlayer2.width,newlayer2.height,0,0)
    sel = pdb.gimp_edit_named_paste(drawable, buffer, 1)
    drawable.translate((tempdrawable.width-newlayer2.width)/2,(tempdrawable.height-newlayer2.height)/2)
  else:
    temp.resize(newlayer2.width,newlayer2.height,0,0)
    sel = pdb.gimp_edit_named_paste(temp, buffer, 1)
    temp.translate((tempdrawable.width-newlayer2.width)/2,(tempdrawable.height-newlayer2.height)/2)

  pdb.gimp_buffer_delete(buffer)
  pdb.gimp_edit_clear(temp)
  pdb.gimp_floating_sel_anchor(sel)

  #load up old selection
  if hassel:
    pdb.gimp_selection_load(savedsel)
    image.remove_channel(savedsel)
  
  # cleanup
  os.remove(tempfilename)  # delete the temporary file
  gimp.delete(tempimage)   # delete the temporary image


  # Modified by ShiroYuki_Mot  LayerName
  newLayerNo = pdb.gimp_image_get_active_layer(image)
  oldLayerName = pdb.gimp_item_get_name(newLayerNo)
  pdb.gimp_item_set_name(newLayerNo, oldLayerName + " > Ext.: " + progtorun[0])
  #End Modified


  # Note the new image is dirty in Gimp and the user will be asked to save before closing.
  pdb.gimp_image_undo_group_end(image)
  gimp.displays_flush()


register(
        "python_fu_shellout",
        "Call an external program",
        "Call an external program",
        "Rob Antonishen",
        "Copyright 2011 Rob Antonishen",
        "2011",
        "<Image>/Filters/ShellOut...",
        "RGB*, GRAY*",
        [ (PF_RADIO, "visible", "Layer:", 1, (("new from visible", 1),("current layer",0))),
          (PF_OPTION,"command",("Program:"),0,listcommands())
        ],
        [],
        plugin_main,
        )

main()



公開が遅くなって仕舞いました。



0 件のコメント:

コメントを投稿