Управление шириной Rasterize[] для выражений, связанных с ноутбуком
Обновленный ответ Mr Wizard дает превосходные по пикселям результаты, но он предназначен только для Windows и уничтожает содержимое буфера обмена. Мой ответ должен работать на любой платформе, но он менее точен: например, он не включает метки In/Out. Это позволяет установить ширину растеризации.
Эта проблема возникла, когда я пытался создать окно предварительного просмотра для загрузчика изображений (см. Конец этого ответа).
Я хотел бы создать кнопку палитры, которая будет загружать текущий выбор блокнота в виде изображения. Перед загрузкой я хотел бы показать предварительный просмотр изображения, чтобы уменьшить вероятность того, что что-то пойдет не так, прежде чем обращаться к серверу.
Это то, что у меня есть (включает только код предварительного просмотра, а не загрузчик):
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
модуль-переменная тоже: это потому, что к тому времени doIt[img]
локальные переменные модуля будут очищены, поэтому мне нужно подставить растеризованное выражение непосредственно в doIt
функция,
Эта кнопка работает (более или менее). Вы можете попробовать это, создав графический объект в той же записной книжке (например, Graphics[Circle[]]
), выбрав его одним щелчком мыши, затем нажав кнопку "Просмотр".
Однако, если я положу его в палитру с помощью CreatePalette[button]
затем произойдет растеризация для ширины окна палитры, и я получу что-то вроде этого:
Как я могу контролировать ширину растеризации или, в более общем смысле, как создать диалоговое окно предварительного просмотра для загрузчика, который позволяет избежать этой проблемы?
Для дополнительного улучшения было бы неплохо иметь возможность изменить размер окна сообщения так, чтобы оно соответствовало изображению предварительного просмотра (и все еще показывает кнопку: кнопка исчезает с WindowSize -> All
).
ответы
Предложение мистера Волшебника:
button = Button[
"Preview", (FrontEndExecute[
FrontEndToken[FrontEnd`SelectedNotebook[], "CopySpecial", "MGF"]];
MessageDialog[
First@Cases[NotebookGet@ClipboardNotebook[],
RasterBox[data_, ___] :>
Image[data, "Byte", ColorSpace -> "RGB", Magnification -> 1],
Infinity]])]
CreatePalette[button]
Проблемы: Он (вероятно) работает только в Windows и уничтожает содержимое буфера обмена.
4 ответа
Мне удалось сделать это, скопировав выделение в новый блокнот, растеризовав полный блокнот, а затем закрыв его.
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 пикселей.
Обратите внимание на некоторые недостатки (в некоторых случаях преимущества) этого метода по сравнению с копированием в виде растрового изображения:
- Пользовательские стили потеряны
- Метки In/Out теряются
- Значение увеличения ноутбука потеряно
Если есть необходимость, некоторые из них могут быть исправлены путем явной передачи некоторых параметров ноутбука из SelectedNotebook
к недавно созданному.
Если в этой операции целесообразно использовать буфер обмена, вы можете использовать: FrontEnd`CopySpecial["MGF"]
(скопировать как растровое изображение).
Я думаю, что это должно работать без необходимости делать новую записную книжку:
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
]
Я использовал маленький поисковик опций, чтобы найти ImageFormattingWidth
и, передав ширину изображения в качестве ширины окна, вы можете сделать так, чтобы диалог хорошо вписывался в картинку и при этом отображал кнопку.
Вот демонстрация его результатов:
Вы пытались использовать 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 и сравнение типа / размера изображения http://i44.tinypic.com/ok6fl.png