简体   繁体   中英

TclTk get image from canvas

I have created a canvas in $gw.sw.sf.frame.c where $gw is a top-level windows sw and sf are a ScrolledWindow and a ScrollableFrame from the BWidget package and c is the canvas ( tk::canvas ). Inside the canvas there are only text and rectangles filled with some color. I can generate a correct eps file from the canvas using:

$can postscript -colormode color -file test.eps

However if I tried to use ::canvas::snap $can in order to get an image and then be able to save a PNG/BMP/TIFF/JPEG image file using the Img package I get the following error:

Window ".graphresults1494146100.sw.sf.frame.c" cannot be transformed into a pixmap (possibly obscured?)
Window ".graphresults1494146100.sw.sf.frame.c" cannot be transformed into a pixmap (possibly obscured?)
    while executing
    "image create photo -data $can"
        (procedure "::mTKs::savegraphres" line 3)
        invoked from within
    "::mTKs::savegraphres .graphresults1494146100.sw.sf.frame.c"
        (menu invoke)

So the questions are:

  1. Is there a way to fix this so I can use ::canvas::snap and then Img to generate the image files?

  2. If not, is there any way to convert the eps file to an image file using only TclTk code? I know I can use Ghostscript or ImageMagic for this purpose but I would like my program to use only TclTk.

  3. Any other way to get the image from the canvas??

Just in case: I am using OS 10.12.4 TclTk 8.6 Img 1.4.6 Tklib 0.6 and BWidget 1.9.10

NEW FACTS

I found that the problem is with the OS X version. At my work I am using 10.10.4 and here the code is able to create the figure but after creating the figure the canvas content goes complete white. I guess that canvas::snap change the stacking order inside the window resulting in an apparent empty canvas, is this correct?

In addition I took the advice from Donal Fellows and create the canvas directly in .toplevelwindow.canvas and with 10.10.4 canvas::snap and Img produce the correct image and the window content is not altered. Using 10.12.4 I got the same error as before. Any work around this?

You're using the mechanism that is supported as part of the Img package (also called tkimg sometimes to distinguish it). The error message was:

Window ".graphresults1494146100.sw.sf.frame.c" cannot be transformed into a pixmap (possibly obscured?)

The problem is that the conversion of a canvas to an image is performed by doing a screen-grab of the canvas (ie, it's the exact same underlying API that any screenshot mechanism uses), which appears to have failed. The most likely reason for the failure is that the canvas wasn't showing on the screen at the time the capture was done; it needs to be on-screen and topmost for the capture to work.

To make a canvas be on-screen, it needs to be managed appropriately by a geometry manager inside a toplevel that is itself mapped. It then needs to be raised to the top of the stack of windows, both within the toplevel and that toplevel relative to the rest of the screen's contents. Often you can do that with:

pack $thecanvas;   # Or “grid $thecanvas” or any of a number of other alternatives
update
raise $thecanvas
raise -force [winfo toplevel $thecanvas]
update
# Do the capture here

However, in your case it is inside a complex stack of widgets so those might be a problem. (For example, they could be forcing the canvas to be mapped off-screen or something like that. All sorts of complexity is possible!) If that's the case, generating the content in another canvas (which only needs to be up for a moment) might be a workaround. I don't know if that canvas needs to be physically visible on the screen, though I suspect it does.


In general, if you're really doing a lot of conversions like this, it is probably better to convert the encapsulated postscript to an image directly instead of via screen capture (as that's always a bit flaky and uncertain). The usual tool for doing that is Ghostscript, often with it being wrapped in the ImageMagick suite, as that can do those conversions without needing to access the user's screen at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM