Copying pictures

About SheepShaver, a PPC Mac emulator for Windows, MacOS X, and Linux that can run System 7.5.3 to MacOS 9.0.4.

Moderators: Cat_7, Ronald P. Regensburg, ClockWise

emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

Ronald P. Regensburg wrote: Thu Aug 26, 2021 7:16 am Now, why doesn't it work here? Could it be because my Mac runs on Apple Silicon?
This seems possible. I will try later on a borrowed M1 Mac.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

Ronald P. Regensburg wrote: Thu Aug 26, 2021 9:23 am An interesting fact that I did not mention before:
The blank (white) image that is opened in Preview or Graphic Converter using 'open new image from clipboard' has the same size in pixels as the image that was copied in SheepShaver.
Together with your file size discrepancies I noticed at viewtopic.php?p=71644#p71644 , that makes me guess that the PICT is correctly written to the clipboard by SheepShaver, but the other formats (like PNG, TIFF, JPG …) are created by the host from the PICT it obtains from SheepShaver.
If this is true, for some reason that conversion goes fine at emendelson’s and my machine, but only produces white pixels at your machine.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

I ran into the same issue now: The image is white while its size correspondents with what was copied in SheepShaver.

a) What I did before (when it still worked):
I used an image that was previously saved as PICT by GraphicConverter in SheepShaver, opened it with PictureViewer (part of QuickTime) and copied it there. On the host I could then “convert” it to PNG by running “set the clipboard to (the clipboard as «class PNGf»)” in AppleScript. “Open new image from clipboard” in Preview worked fine.

b) What I did now (when it wouldn’t work):
I opened the example picture that comes with QuickTime in PictureViewer and copied it there. After running “set the clipboard to (the clipboard as «class PNGf»)” on the host, “Open new image from clipboard” in Preview produced a white image while dimensions were preserved.

I then tested the following:
After copying the image as described under a), I ran the following AppleScript on the host:

Code: Select all

set clipFile to (path to home folder as Unicode text) & "clipboardConvFile.pct"

set theOpenedFile to open for access file clipFile with write permission

-- clear file content
set eof of theOpenedFile to 0

write (the clipboard as picture) to theOpenedFile starting at eof

close access theOpenedFile
[This is, by the way, the solution to my post viewtopic.php?p=71628#p71628 : “write (the clipboard as picture) …” i.s.o. “write (the clipboard) …”]
That would write the PICT data to the file clipboardConvFile.pct which I then copied into SheepShaver. There it opened fine with both, GraphicConverter and PictureViewer.

Then, after copying the image as described under b), I repeated this procedure. Now PictureViewer opened it as a white image while GraphicConverter opened it fine.

So depending on how the PICT data on the clipboard is generated, the host does or does not succeed in properly converting it to other formats. And even within SheepShaver the results don't seem to be consistent.

Next I want to try ImageMagick to see whether it does the job reliably.
User avatar
adespoton
Forum All-Star
Posts: 4226
Joined: Fri Nov 27, 2009 5:11 am
Location: Emaculation.com
Contact:

Re: Copying pictures

Post by adespoton »

Is everyone using 9.0.4 inside SheepShaver?

And something's niggling at the back of my mind regarding the PICT format and QuickDraw and how the output is generated... but it's something I vaguely remember from System 6 days. Possibly the way PICT image data was stored to the clipboard changed? So older applications would still use the old method and newer applications would use the new method.
emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

mabam's method works for me on an M1 Mac running Big Sur. I open a PICT file in GrahpicConverter in SheepShaver, copy it to the clipboard, then run an item from my Apple Menu that writes a file to the host; the host, when it detects the existence of that file, runs mabam's script - and the copied image is now visible in the host Clipboard. (The file that I write to the host is empty - it doesn't contain, any information. But its existence triggers my host setup to run mabam's script.)

One possibility is this: there are two kinds of PICT file, I think. The ones created by QuickTime have a larger bit depth than the ones created by GraphicConverter or the ones created when you save the desktop to the clipboard in SheepShaver. They have different creator types. SimpleText can't display the ones with the larger bit depth. It's possible (I haven't tested this, and I am ONLY guessing) that the conversion doesn't work when the image has the larger bit depth, though I wouldn't want to test why. Could those of us who are seeing problems test whether the test file that you're using will open in SimpleText? If not, that may be the answer.

And yes, my guess is that we're all running 9.0.4 in SheepShaver.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

Yes, I’m running 9.0.4.

For some reason the PICT in the clipboard doesn’t contain a header. If I save as PICT from GraphicConverter in SheepShaver, the header is just null data up to offset 522. But no matter whether I use that image or prepend the header manually to what I have saved from the clipboard: ImageMagick errors out with “improper image header”.

mabam wrote: Thu Aug 26, 2021 2:37 pm b) What I did now (when it wouldn’t work):
I opened the example picture that comes with QuickTime in PictureViewer and copied it there. After running “set the clipboard to (the clipboard as «class PNGf»)” on the host, “Open new image from clipboard” in Preview produced a white image while dimensions were preserved.
When copying the example picture from QuickTime, looking at the clipboard’s content I figured it contains JPEG data though the clipboard identifies it as PICT. It seems like it is a JPEG in a QuickTime wrapper as described at http://fileformats.archiveteam.org/wiki/PICT under “Related formats”. So that could be the reason why it’s just white after conversion.


EDIT:
Just for reference – this AppleScript will create a PICT file from the clipboard with a valid header (despite ImageMagick still not liking it):

Code: Select all

set pictHeader to «data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000»

set clipFile to (path to home folder as Unicode text) & "pictFromClipboard.pct"
set theOpenedFile to open for access file clipFile with write permission

set eof of theOpenedFile to 0 -- Clear file content
write pictHeader to theOpenedFile starting at eof
write (the clipboard as picture) to theOpenedFile

close access theOpenedFile
Last edited by mabam on Fri Aug 27, 2021 10:12 am, edited 4 times in total.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

emendelson wrote: Thu Aug 26, 2021 6:42 pm One possibility is this: there are two kinds of PICT file, I think. The ones created by QuickTime have a larger bit depth than the ones created by GraphicConverter or the ones created when you save the desktop to the clipboard in SheepShaver. They have different creator types. SimpleText can't display the ones with the larger bit depth. It's possible (I haven't tested this, and I am ONLY guessing) that the conversion doesn't work when the image has the larger bit depth, though I wouldn't want to test why. Could those of us who are seeing problems test whether the test file that you're using will open in SimpleText? If not, that may be the answer.

My non-working file doesn’t open in SimpleText. But the reason is probably the JPEG data in my case, as described in my last post.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

I just found Deark: https://github.com/jsummers/deark

From the non-working PICT file it would extract a QTIF file and from that, in a second run, a JPEG file.
This should also work for other image formats. It can probably be automated together with a script that copies the now readable image format back to the clipboard.
emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

mabam wrote: Fri Aug 27, 2021 12:19 am I just found Deark: https://github.com/jsummers/deark

From the non-working PICT file it would extract a QTIF file and from that, in a second run, a JPEG file.
This should also work for other image formats. It can probably be automated together with a script that copies the now readable image format back to the clipboard.
This looks very interesting. I've lost track of details. Do you have a way to get the non-working PICT data from the host clipboard to a file?
User avatar
Ronald P. Regensburg
Expert User
Posts: 7821
Joined: Thu Feb 09, 2006 10:24 pm
Location: Amsterdam, Netherlands

Re: Copying pictures

Post by Ronald P. Regensburg »

I lost track. I will wait till a workable solution is found.

In te meantime, this works with all image formats:
- Create a desktop printer that can print to a PostScript file
- Use that printer to print the image to file and save the .ps file in Unix
- On the host side the .ps file can be opened in Preview
- Copying from Preview works as expected
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

emendelson wrote: Fri Aug 27, 2021 12:50 am This looks very interesting. I've lost track of details. Do you have a way to get the non-working PICT data from the host clipboard to a file?

This will get any PICT data from the clipboard to a file including a 512-byte header:
mabam wrote: Thu Aug 26, 2021 6:57 pm EDIT:
Just for reference – this AppleScript will create a PICT file from the clipboard with a valid header (despite ImageMagick still not liking it):

Code: Select all

set pictHeader to «data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000»

set clipFile to (path to home folder as Unicode text) & "pictFromClipboard.pct"
set theOpenedFile to open for access file clipFile with write permission

set eof of theOpenedFile to 0 -- Clear file content
write pictHeader to theOpenedFile starting at eof
write (the clipboard as picture) to theOpenedFile

close access theOpenedFile

The resulting file can then be processed by Deark to get the core content out of the container (sometimes multiple containers):

Code: Select all

deark -k ~/clipboardConvFile.pct
The file with the resulting content (e. g. PNG or JPEG) can then be picked up by this command line tool that copies it back to the clipboard:

Code: Select all

impbcopy ~/clipboardConvFile.pct.000.png

Works all fine when I enter the commands in Terminal. It’s just a matter of turning it into a script which will take some time for the Deark part as the script needs to provide some automation Deark doesn’t ship with (processing the file multiple times in case of multiple containers).

Another thing will be distribution as I can’t code-sign anything.
emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

mabam, that is really excellent. Well done!

Here is a first try at an AppleScript application (notarized) based on your method:

http://www.columbia.edu/~em36/ConvertClipboardPICT.zip

I changed some file locations to get around restrictions on file access, and made a few other minor changes which probably were not necessary. (I misunderstood some error messages, and changed things to fix them, but didn't really need to.)

What the script needs is a way to test the clipboard to see if it has the kind of PICT data created by the SheepShaver clipboard. I've added a test for image data, but I don't know how to test for the specific data created by SheepShaver.

And here is the code (which requires the two helper executables in the location specified). I don't really know AppleScript, so this is very badly written, and any improvements will be welcome.

Code: Select all

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

try
	the clipboard as TIFF picture
on error
	display dialog "No image data in the clipboard." buttons {"OK"} giving up after 5
	error number -128
end try

set myPath to POSIX path of (path to me)
set helpers to myPath & "Contents/Resources/Helpers/"
set dearkPath to quoted form of (helpers & "deark")
set impbcopyPath to quoted form of (helpers & "impbcopy")

set pictHeader to «data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000»

try
	set clipFile to POSIX path of (path to documents folder as text) & "clipboardConvFile.pct"
	set theOpenedFile to open for access clipFile with write permission
	set eof of theOpenedFile to 0 -- Clear file content
	write pictHeader to theOpenedFile starting at eof
	write (the clipboard as picture) to theOpenedFile
	close access theOpenedFile
on error err
	display dialog err
	error number -128
end try

try
	do shell script dearkPath & space & "-k ~/Documents/clipboardConvFile.pct -t ~/Documents/toClipboard.png"
on error err
	if err contains "permission error" then
		display dialog "The converter program was unable to convert the image." buttons ("OK") giving up after 5
		try
			do shell script "rm -f" & space & "~/Documents/toClipboard.png"
		end try
		error number -128
	else
		display dialog "Deark error:" & return & return & err
	end if
end try

try
	do shell script impbcopyPath & space & "~/Documents/toClipboard.png"
on error err
	display dialog "Could not copy the converted image to the clipboard." & return & return & err buttons {"OK"} giving up after 5
	try
		do shell script "rm -f" & space & "~/Documents/toClipboard.png"
	end try
end try

try
	do shell script "rm -f" & space & "~/Documents/toClipboard.png"
end try

try
	do shell script "rm -f" & space & "~/Documents/clipboardConvFile.pct"
end try
User avatar
Ronald P. Regensburg
Expert User
Posts: 7821
Joined: Thu Feb 09, 2006 10:24 pm
Location: Amsterdam, Netherlands

Re: Copying pictures

Post by Ronald P. Regensburg »

Works perfectly here. :smile:
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

emendelson, great work!
I couldn’t have produced that base script in the time you did. And I have only learned AppleScript by trial and error myself. So you provide pieces of script in a convenient way I wouldn’t have thought of myself.
  • I have amended the clipboard test so the script only runs if PICT data is on the first position of the “clipboard info”. I think that will only be the case if copied from SheepShaver.
  • I’ve added a line to close access to the file if writing the PICT file from the clipboard fails. Otherwise the file stays open in AppleScript globally, I think, which would give an error on a subsequent run.
  • I’ve added a loop for Deark in case there is more than one container in the PICT file. If there is, a dynamic way of file name handling is required. That’s also true for the file extensions because the core content is not necessarily PNG. So I have implemented that.
  • For all the “rm” shell scripts, (next to the file name due to the now dynamic name handling) I’ve changed the file extensions to “*” so that not only PNGs and PICTs are deleted.
  • I’ve removed a try block and am not sure about some of the others. I think “error number -128” doesn’t stop the script if in a try block. That’s still something to look into.
Here’s the amended code:

Code: Select all

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

if item 1 of item 1 of (clipboard info) as string is not "picture" then
	display dialog "No PICT data on the clipboard." buttons {"OK"} giving up after 5
	error number -128
end if

set myPath to POSIX path of (path to me)
set helpers to myPath & "Contents/Resources/Helpers/"
set dearkPath to quoted form of (helpers & "deark")
set impbcopyPath to quoted form of (helpers & "impbcopy")

set pictHeader to «data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000»

try
	set clipFile to POSIX path of (path to documents folder as text) & "clipboardConvFile.pct"
	set theOpenedFile to open for access clipFile with write permission
	set eof of theOpenedFile to 0 -- Clear file content
	write pictHeader to theOpenedFile starting at eof
	write (the clipboard as picture) to theOpenedFile
	close access theOpenedFile
on error err
	try
		close access theOpenedFile
	end try
	display dialog err
	error number -128
end try

try
	set sourceExtension to "pct"
	repeat
		set dearkResponse to paragraph -1 of (do shell script dearkPath & " -l -maxfiles 1 ~/Documents/clipboardConvFile." & sourceExtension)
		if dearkResponse is "No files found to extract!" then
			exit repeat
		else
			set destExtension to word -1 of dearkResponse
		end if
		do shell script dearkPath & " ~/Documents/clipboardConvFile." & sourceExtension & " -t ~/Documents/clipboardConvFile." & destExtension
		set sourceExtension to destExtension
	end repeat
on error err
	if err contains "permission error" then
		display dialog "The converter program was unable to convert the image." buttons ("OK") giving up after 5
		try
			do shell script "rm -f" & space & "~/Documents/clipboardConvFile.*"
		end try
		error number -128
	else
		display dialog "Deark error:" & return & return & err
	end if
end try

try
	do shell script impbcopyPath & space & "~/Documents/clipboardConvFile." & destExtension
on error err
	display dialog "Could not copy the converted image to the clipboard." & return & return & err buttons {"OK"} giving up after 5
	try
		do shell script "rm -f" & space & "~/Documents/clipboardConvFile.*"
	end try
end try

try
	do shell script "rm -f" & space & "~/Documents/clipboardConvFile.*"
end try

It’s only a pity that impbcopy seems to always add the image to the clipboard as TIFF, no matter what the current format of the file created by Deark is. That makes the data unnecessarily bigger. But I’m glad it works.

I’ve uploaded an example picture that comes with QuickTime here (unzip on the host):
https://c.web.de/@337526389169198226/VB ... gXcmqqUaYA
It’s a JPEG in a QTIF container in a PICT container. If anyone wants to try, copy it into SheepShaver, open it with PictureViewer (part of QuickTime) and hit cmnd-C. Now run the script on the host and you should be able to paste it into Preview.
emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

mabam, your changes are far better than anything I could have thought of by myself, especially since I haven't experimented with deark at all. I can never be certain how to exit a script, so I simply throw in a lot of "error number -128" lines where I think they will work. Eventually, maybe, I'll figure this out.

I've notarized your version of the script, and it's at the same link as in my previous post. Thank you!
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

Thank you for updating the binary, works fine!
emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

I've been experimenting with adding an option to displays a preview image of the file that was copied to the clipboard, but I don't know enough about shell scripting to make it work exactly as I want. I've added a variable named showImage that you can either turn on in the code or enable by changing the name of the app so that it includes the word "Show". Then the script adds this code after the converted file is generated:

Code: Select all

if showImage is true then
	try
		do shell script "qlmanage -p ~/Documents/clipboardConvFile." & destExtension & space & " & QL_PID=$! && read -rsn1 && kill $QL_PID"
	end try
end if
This displays the file and waits for the user to press any key. When the user presses a key, the preview image disappears and the script continues. The try block prevents an error message from appearing - and of course I would prefer not to have the error message at all, but I don't know exactly what is causing the error.

What would be best would be a way to timeout the image after a few seconds if the user doesn't press any key, but I can't figure out how to get the PID of the qlmanage instance. I'll ask on one of the AppleScript forums.
User avatar
Ronald P. Regensburg
Expert User
Posts: 7821
Joined: Thu Feb 09, 2006 10:24 pm
Location: Amsterdam, Netherlands

Re: Copying pictures

Post by Ronald P. Regensburg »

I would rather not see a preview. It takes extra time and needs additional action.
emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

Ronald P. Regensburg wrote: Sat Aug 28, 2021 3:54 pm I would rather not see a preview. It takes extra time and needs additional action.
As I said in my post, you would have to turn this option ON explicitly, which you can do either by modifying the AppleScript code or by changing the name of the application so that it includes the word "Show." If you do not do either of those things, nothing will change. No preview will appear.

You will not see a preview unless you really, really want to, and you will only see the preview if you show that you want to see it, which you can do by making either of the two changes I described.

EDIT: Now that I think about it, it would be easy to add a few lines to the code that would show the preview if you hold down the Option key when launching the script.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

emendelson wrote: Sat Aug 28, 2021 4:10 pm EDIT: Now that I think about it, it would be easy to add a few lines to the code that would show the preview if you hold down the Option key when launching the script.
But if one wants to run the script with an assigned shortcut containing the option key, wouldn’t that interfere?

Maybe you could implement that option with a switch that disables it if the word “NoOpt” is in the name of the app, next to the word ”Show” as switch that always enables the image preview.

I have some improvements to the conversion script ready. I’ll post them once I’ve written the related descriptions.
emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

mabam wrote: Sat Aug 28, 2021 5:14 pm
emendelson wrote: Sat Aug 28, 2021 4:10 pm EDIT: Now that I think about it, it would be easy to add a few lines to the code that would show the preview if you hold down the Option key when launching the script.
But if one wants to run the script with an assigned shortcut containing the option key, wouldn’t that interfere?
You are absolutely right. I won't do anything about this until your new code is ready, and I'll probably set it up so that you will need to enable the Option-key by modifying the code itself. That way, the option key will do nothing unless the user explicitly modifies the code so that it opens the preview image.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

I actually like your idea of amending the app’s file name in order to activate/deactivate things. ’Cause I think for the average user that’s way easier than changing something in the code.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

Here my amendments to the script:
  1. First off, AppleScript prepends four letters for the data descriptor type to the hex values in «data …». So for the pictHeader I’ve set those to “PICT”. I doubt it matters in this case, but just to make the code as clean as possible.
    .
  2. I’ve now added some lines to the script that, if Deark’s output is a PNG, JPEG, TIFF, GIF, or BMP, will write that image data back to the clipboard as is.
    mabam wrote: Fri Aug 27, 2021 10:42 pm It’s only a pity that impbcopy seems to always add the image to the clipboard as TIFF, no matter what the current format of the file created by Deark is. That makes the data unnecessarily bigger. But I’m glad it works.
    For any other image format impbcopy is used to write it to the clipboard as TIFF, followed by a line of AppleScript that then replaces it by a smaller but lossless PNG version.

    emendelson, I know you hate it when people waste your time. But you’ll have to withstand this little anecdote on point 2 now (in grey), I’m afraid. I hope it’s not killing you … ;-)

    When working on a solution for the copying issue during the past days, I only came across forums where people posted that it is not possible to use AppleScript for reading an image file and copying it to the clipboard. But I was a little stubborn on that and today I found, inspired by the output of “return the clipboard” (if it holds an image), that it is possible to manually “set testVar to {picture:«data PNGf00000000»}” and, inspired by “set the clipboard to (the clipboard as «class PNGf»)” and the output of “return clipboard info” (which I both found on the web earlier), that it is possible to copy (fake) image data to the clipboard with this line:

    Code: Select all

    set the clipboard to {picture:«data PNGf00000000»}
    When then running “return the clipboard” the result is

    Code: Select all

    {«class PNGf»:«data PNGf00000000»}

    This means that the data descriptor type “PNGf” (which I have prepended to the hex values) determines «class PNGf» which automatically replaces the “picture” part of my entry.
    (If I omit “picture:” alltogether, the output of “return the clipboard” is: “{list:{«data PNGf00000000»}}”, which the clipboard can be set to, but is not recognised as an image – you can’t paste it anywhere as such.)

    So after I figured how to write the data to the clipboard properly – knowing by now that data cannot be parsed in AppleScript, only read or written – I couldn’t stand the thought that it shouldn’t be possible to assign the correct class and data descriptor while reading data from an image file.
    “read (POSIX path of (path to Documents folder as text) & "clipboardConvFile.png") as data” works for reading a file as hex values. But the output is just «data rdat00000000…». So the class is wrong and the data descriptor is set to AppleScript’s standard “rdat” which doesn’t identify as an image.

    Then I found this (under the third code block from the bottom) [https://macscripter.net/viewtopic.php?id=24745]:
    For advanced, specialist, or eccentric users, as also accepts four-character string codes such as "TEXT", "utxt", "PICT", "isot", etc. The four mentioned here are equivalent to string («class TEXT»), Unicode text («class utxt»), picture («class PICT»), and the keywordless «class isot».
    I guess I’m the eccentric type of user, so this is for me. ;-)

    The example string codes reminded me of the output of “return clipboard info”. And combining this with the above mentioned manual method to set the clipboard to image data including class and data descriptor, I found this entry reads the image file properly and sets the clipboard to its content:

    Code: Select all

    set the clipboard to {picture:(read (POSIX path of (path to documents folder as text) & "clipboardConvFile.png") as PNGf)}
    .
  3. Also, in case writing to the clipboard fails, Deark’s output is not deleted immediately but moved to the trash (with a dialog informing about that) so the user can collect the file from there and open it with an application of choice.
Here’s the code:

Code: Select all

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

if item 1 of item 1 of (clipboard info) as string is not "picture" then
	display dialog "No PICT data on the clipboard." buttons {"OK"} giving up after 5
	error number -128
end if

set myPath to POSIX path of (path to me)
set helpers to myPath & "Contents/Resources/Helpers/"
set dearkPath to quoted form of (helpers & "deark")
set impbcopyPath to quoted form of (helpers & "impbcopy")

set pictHeader to «data PICT0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000»

try
	set clipFile to POSIX path of (path to documents folder as text) & "clipboardConvFile.pct"
	set theOpenedFile to open for access clipFile with write permission
	set eof of theOpenedFile to 0 -- Clear file content
	write pictHeader to theOpenedFile starting at eof
	write (the clipboard as picture) to theOpenedFile
	close access theOpenedFile
on error err
	try
		close access theOpenedFile
	end try
	display dialog err
	error number -128
end try

try
	set sourceExtension to "pct"
	repeat
		set dearkResponse to paragraph -1 of (do shell script dearkPath & " -l -maxfiles 1 ~/Documents/clipboardConvFile." & sourceExtension)
		if dearkResponse is "No files found to extract!" then
			exit repeat
		else
			set destExtension to word -1 of dearkResponse
		end if
		do shell script dearkPath & " ~/Documents/clipboardConvFile." & sourceExtension & " -t ~/Documents/clipboardConvFile." & destExtension
		set sourceExtension to destExtension
	end repeat
on error err
	if err contains "permission error" then
		display dialog "The converter program was unable to convert the image." buttons ("OK") giving up after 5
		try
			do shell script "rm -f" & space & "~/Documents/clipboardConvFile.*"
		end try
		error number -128
	else
		display dialog "Deark error:" & return & return & err
	end if
end try

try
	if destExtension is in {"png", "tif", "jpg", "gif", "bmp"} then
		if destExtension is "png" then
			set imgFormat to "PNGf"
		else if destExtension is "tif" then
			set imgFormat to "TIFF"
		else if destExtension is "jpg" then
			set imgFormat to "JPEG"
		else if destExtension is "gif" then
			set imgFormat to "GIFf"
		else if destExtension is "bmp" then
			set imgFormat to "BMPf"
		end if
		set the clipboard to {picture:(read (POSIX path of (path to documents folder as text) & "clipboardConvFile." & destExtension) as imgFormat)}
	else
		do shell script impbcopyPath & space & "~/Documents/clipboardConvFile." & destExtension -- Copies the image to the clipboard as TIFF.
		set the clipboard to (the clipboard as «class PNGf») -- Copies a compressed PNG version of the image to the clipboard.
	end if
on error err
	set trashDialog to ""
	try
		set trashDialog to return & return & "Move the converted image file out of the trash if needed."
		tell application "Finder" to move file ((path to documents folder as text) & "clipboardConvFile." & destExtension) as text to trash
	on error
		set trashDialog to ""
	end try
	display dialog "Could not copy the converted image to the clipboard." & trashDialog & return & return & err buttons {"OK"} giving up after 5
	try
		do shell script "rm -f" & space & "~/Documents/clipboardConvFile.*"
	end try
end try

try
	do shell script "rm -f" & space & "~/Documents/clipboardConvFile.*"
end try
EDIT: Corrected path of file to be moved to trash.
Last edited by mabam on Sun Aug 29, 2021 12:49 pm, edited 1 time in total.
emendelson
Forum All-Star
Posts: 1706
Joined: Tue Oct 14, 2008 12:12 am

Re: Copying pictures

Post by emendelson »

Good stories full of information and reports of discoveries are NEVER time-wasting. Thank you for all those details. You've made it easier for other people to find related information. This is all excellent in every way. I'll add a few lines to your code making it possible to use the Option key to show the preview IF the app is renamed with a string like "key" or "alt" in it.

It would be very good to have a preview app that could display the contents of the clipboard from AppleScript or the command line, but it doesn't seem to exist. An expert programmer posted the start of one here:

https://macscripter.net/viewtopic.php?id=48628

But I can't figure out how to add an OK button or to make it go away with a keystroke. It's surprising that a clipboard viewer app never got written before this.

Will post revised code in the next few days. Thanks again for that very useful and fascinating information.
User avatar
mabam
Master Emulator
Posts: 497
Joined: Wed Apr 10, 2013 9:32 am

Re: Copying pictures

Post by mabam »

emendelson wrote: Sun Aug 29, 2021 2:23 am You've made it easier for other people to find related information.
That was part of my intention. The other part was ordering and documenting it for myself.

emendelson wrote: Sun Aug 29, 2021 2:23 am It would be very good to have a preview app that could display the contents of the clipboard from AppleScript or the command line, but it doesn't seem to exist. An expert programmer posted the start of one here:

https://macscripter.net/viewtopic.php?id=48628

But I can't figure out how to add an OK button or to make it go away with a keystroke. It's surprising that a clipboard viewer app never got written before this.
When I first read of your idea of displaying the clipboard image after conversion, my first thought was to preview it automatically like selecting a file and hitting space in Finder does manually. That’s what member wch1zpink does at https://macscripter.net/viewtopic.php?p ... 74#p207874 with the AppleScript code he provides. And that preview can easily be escaped by pressing esc or space.
Though member KniazidisR says this is slower than his AsObjC code, I don’t think that’s true in our particular case. Because Deark already writes the converted image to disk before putting it on the clipboard, it is quick and easy to have

Code: Select all

do shell script "/usr/bin/qlmanage -p " & (POSIX path of (path to trash as text) & "clipboardConvFile." & destExtension)
preview it. (I only have to change the code so the resulting image is always moved to the trash first – ’cause we need the preview after the error handler for impbcopy.)

After launching qlmanage (which the above line does in order to display the image), adding the following will make the preview disappear after five seconds if the user didn’t already do so by pressing space or esc (or even cmnd-Q):

Code: Select all

delay 5
try
	tell application "qlmanage" to quit
end try
EDIT:
AppleScript waits for the shell script to exit before it continues with the delay and quitting qlmanage, so I’ll have to change this to be handled in the shell script.
Post Reply