控制与笔记本相关的表达式的Rasterize []宽度

时间:2011-12-02 08:53:11

标签: wolfram-mathematica mathematica-frontend

更新先生的回答给出了像素完美的结果,但它只是Windows并且会破坏剪贴板内容。我的答案应该适用于任何平台,但它不太精确:例如它省略了输入/输出标签。它确实允许设置光栅化宽度。


当我trying to make a preview window for an image uploader时出现了这个问题(请参阅该答案的结尾)。

我想创建一个调色板按钮,将当前笔记本选择上传为图像。在上传之前,我想展示一下图片的预览,以减少在联系服务器之前出错的可能性。

这是我到目前为止(仅包括预览代码,而不是上传者):

button = Button[
  "Preview",
  Module[
    {expr = NotebookRead@InputNotebook[]}, 
    If[expr =!= {},
      With[{img = Rasterize[expr]},
        MessageDialog[
          Column[{"Would you like to perform the action?", img}], 
          {"Do it!" :> doIt[img], "Cancel" :> Null}
        ]
      ]
    ]
  ]
]

如果您想知道为什么我在With中使用嵌套Module而不是使img成为模块变量:那是因为到时{{1}在评估时,本地模块变量将被清除,因此我需要将栅格化表达式直接替换为doIt[img]函数,

此按钮有效(或多或少)。您可以通过在同一笔记本中创建图形(例如doIt),单击选择它,然后单击预览按钮来尝试。

但是,如果我使用Graphics[Circle[]]将它放在调色板中,那么光栅化将发生在调色板的窗口宽度上,我会得到这样的结果:

Screenshot of the problem

如何控制光栅化的宽度,或者更一般地说,如何为上传器创建避免此问题的预览对话框?

为了进一步改进,最好能够调整消息窗口的大小以使其适合预览图像(并且仍然显示按钮:按钮随CreatePalette[button]消失)。


答案

先生。巫师的建议:

WindowSize -> All

问题:它(可能)仅适用于Windows,它会破坏剪贴板内容。

4 个答案:

答案 0 :(得分:2)

如果在此操作中使用剪贴板是可行的,您可以使用:FrontEnd`CopySpecial["MGF"](复制为位图)。

答案 1 :(得分:1)

我设法通过将选择复制到新笔记本,光栅化整个笔记本,然后关闭它来实现这一目的。

CreatePalette@Button["Preview",
  Module[{target},
   target = 
    CreateDocument[{}, WindowSelected -> False, Visible -> False];
   NotebookWrite[target, NotebookRead[SelectedNotebook[]]];
   CreateDialog[{Rasterize[target], DefaultButton[]}];
   NotebookClose[target]
   ]
  ]

可以将WindowSize -> 500选项添加到CreateDocument,将栅格化宽度设置为500像素。


与复制为位图相比,请注意此方法的一些缺点(在某些情况下有优势):

  • 自定义样式丢失
  • 输入/输出标签丢失
  • 笔记本电脑放大率值丢失

如果有需要,可以通过将一些笔记本选项从SelectedNotebook显式转移到新创建的笔记本选项来解决其中一些问题。

答案 2 :(得分:0)

您是否尝试过使用ExportString []将图形创建到内存中? (技术上是一个临时文件,但你关心什么:])

ExportString[your_mathematica_stuff_here,"PNG",Background->None]

查看彩色背景上的输出以验证透明BG:

Framed[ImportString[ExportString[x^2,"PNG",Background->None]
                    ,"PNG"]
       ,Background->Yellow]

对于具有多种颜色变化的图像(如3D绘图),我建议使用JPEG2000格式,对于不需要透明度的纯色图像,请使用GIF保留颜色细节。

是的,您可以在导出图像的字符串时控制ImageSize。


ExportString output and image type/size comparison http://i44.tinypic.com/ok6fl.png

答案 3 :(得分:0)

我认为这应该可以在不需要制作新笔记本的情况下使用:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="tabs">
  <ul class="mytabs">
    <li class="active"><a href="#yoursaved">Your History</a>
    </li>
    <li><a href="#yourdetails">Your Details</a>
    </li>
    <li><a href="#yourcar">Your Car</a>
    </li>

  </ul>
</div>

<div id="tab">
  <div id="yoursaved" class="tab-content">
    <p>tab 1</p>
  </div>

  <div id="yourdetails" class="tabs">
    <p>tab 2</p>
  </div>

  <div id="yourcar" class="tabs">
    <p>tab 3</p>
  </div>

</div>

我使用了一个小选项搜索器来查找button = Button["Preview", Module[{expr = NotebookRead@InputNotebook[]}, If[expr =!= {}, With[{img = Rasterize[expr, ImageFormattingWidth -> First@(WindowSize /. AbsoluteOptions[InputNotebook[], WindowSize])]}, MessageDialog[ Column[{"Would you like to perform the action?", img}], {"Do it!" :> doIt[img], "Cancel" :> Null}, WindowSize -> {First@ImageDimensions@img, All}]]]]]; CreateDialog[button, WindowFloating -> True, WindowClickSelect -> False, Selectable -> False ] ,并将图像宽度作为窗口宽度传递,您可以使对话框很好地适合图片并仍然显示按钮。

以下是其结果的演示:

Rasterizing a cell from a pallete