mirror of
https://github.com/WolframResearch/WolframLanguageForJupyter.git
synced 2025-04-15 19:26:04 +00:00
Add a top-level symbol for controlling the resolution of the output
This commit is contained in:
parent
12ed6ff52b
commit
6e5b6cc6e3
@ -72,7 +72,7 @@ If[
|
||||
(* redirect Print calls into a message to Jupyter, in order to print in the Jupyter notebook *)
|
||||
(* TODO: review other methods: through EvaluationData or WSTP so we don't redefine Print *)
|
||||
Unprotect[Print];
|
||||
Print[args___, opts:OptionsPattern[]] :=
|
||||
Print[ourArgs___, opts:OptionsPattern[]] :=
|
||||
Block[
|
||||
{
|
||||
$inPrint=True,
|
||||
@ -80,7 +80,7 @@ If[
|
||||
},
|
||||
If[
|
||||
!FailureQ[First[$Output]],
|
||||
Print[args, opts];
|
||||
Print[ourArgs, opts];
|
||||
loopState["printFunction"][
|
||||
Import[$Output[[1,1]], "String"]
|
||||
];
|
||||
|
@ -202,7 +202,34 @@ If[
|
||||
applyHook[hook_, value_] /; Length[OwnValues[hook]] != 0 := hook[value];
|
||||
applyHook[hook_, value_] := value;
|
||||
Attributes[applyHook] := HoldAll;
|
||||
|
||||
(* the DPI used by browsers according to the CSS standard:
|
||||
https://www.w3.org/TR/css3-values/#absolute-lengths *)
|
||||
cssResolutionDPI = 96;
|
||||
|
||||
(* a top-level symbol for controlling the resolution of the output *)
|
||||
Global`$JupyterResolutionDPI =
|
||||
(* do not allow a value less than cssResolutionDPI as a default value for this *)
|
||||
Max[
|
||||
cssResolutionDPI,
|
||||
(* look in SystemInformation for relevant resolutions *)
|
||||
FirstCase[
|
||||
Quiet[UsingFrontEnd[SystemInformation["Devices", "ScreenInformation"]]],
|
||||
Verbatim[Rule]["Resolution", dpi_?IntegerQ] -> dpi,
|
||||
72,
|
||||
Infinity
|
||||
]
|
||||
];
|
||||
|
||||
(* a safe form of Global`$JupyterResolutionDPI *)
|
||||
safeJupyterResolutionDPI :=
|
||||
First[
|
||||
Replace[
|
||||
{Global`$JupyterResolutionDPI},
|
||||
Except[{value_ /; (IntegerQ[value] && value > 0)}] -> {cssResolutionDPI}
|
||||
]
|
||||
];
|
||||
|
||||
(* can we use the Front End? *)
|
||||
$canUseFrontEnd := (UsingFrontEnd[$FrontEnd] =!= Null);
|
||||
|
||||
|
@ -31,7 +31,10 @@ If[
|
||||
|
||||
Get[FileNameJoin[{DirectoryName[$InputFileName], "Initialization.wl"}]]; (* $canUseFrontEnd, $outputSetToTeXForm,
|
||||
$outputSetToTraditionalForm,
|
||||
$trueFormatType, failedInBase64 *)
|
||||
$trueFormatType,
|
||||
safeJupyterResolutionDPI,
|
||||
cssResolutionDPI,
|
||||
failedInBase64 *)
|
||||
|
||||
(************************************
|
||||
private symbols
|
||||
@ -234,28 +237,88 @@ If[
|
||||
toImageData[result_] :=
|
||||
Module[
|
||||
{
|
||||
(* whether the result has been "pre-rasterized" *)
|
||||
preRasterized,
|
||||
(* the preprocessed form of a result *)
|
||||
preprocessedForm
|
||||
preprocessedForm,
|
||||
(* the result of this operation *)
|
||||
byteArrayResult,
|
||||
(* the dimensions of the image to use *)
|
||||
imageDimensions
|
||||
},
|
||||
|
||||
(* preprocess the result *)
|
||||
preRasterized = (Head[result] =!= Manipulate);
|
||||
If[
|
||||
Head[result] === Manipulate,
|
||||
preprocessedForm = result;
|
||||
preRasterized,
|
||||
(* rasterize the result *)
|
||||
preprocessedForm =
|
||||
Rasterize[
|
||||
result,
|
||||
ImageResolution -> safeJupyterResolutionDPI
|
||||
];
|
||||
(* if the preprocessing failed, return $Failed *)
|
||||
If[
|
||||
FailureQ[preprocessedForm],
|
||||
Return[{$Failed, $Failed}];
|
||||
];
|
||||
(* the "natural" image dimensions of preprocessedForm do not appear to be easily predictable,
|
||||
so just use the dimensions of preprocessedForm when rasterized (again) at 72 DPI *)
|
||||
imageDimensions =
|
||||
Rasterize[
|
||||
result,
|
||||
"BoundingBox",
|
||||
ImageResolution -> 72
|
||||
];
|
||||
If[
|
||||
(FailureQ[imageDimensions]) ||
|
||||
(!ListQ[imageDimensions]) ||
|
||||
(Length[imageDimensions] < 2),
|
||||
Return[{$Failed, $Failed}];
|
||||
];
|
||||
imageDimensions =
|
||||
ToString /@
|
||||
IntegerPart[imageDimensions[[1;;2]]/72 * cssResolutionDPI * (* also, reduce the size of the image somewhat *) 4/5];
|
||||
,
|
||||
preprocessedForm = Rasterize[result];
|
||||
(* do not preprocess, and do not set imageDimensions *)
|
||||
preprocessedForm = result;
|
||||
];
|
||||
(* if the preprocessing failed, return $Failed *)
|
||||
If[
|
||||
FailureQ[preprocessedForm],
|
||||
Return[$Failed];
|
||||
];
|
||||
(* now return preprocessedForm as a byte array corresponding to the PNG format *)
|
||||
Return[
|
||||
|
||||
(* save preprocessedForm as a byte array corresponding to the PNG format *)
|
||||
byteArrayResult =
|
||||
ExportByteArray[
|
||||
preprocessedForm,
|
||||
"PNG"
|
||||
]
|
||||
"PNG",
|
||||
ImageResolution -> safeJupyterResolutionDPI
|
||||
];
|
||||
If[
|
||||
FailureQ[byteArrayResult],
|
||||
Return[{$Failed, $Failed}];
|
||||
];
|
||||
|
||||
(* for Manipulate results, where the image dimensions are not yet determined, read in the metadata of byteArrayResult *)
|
||||
If[
|
||||
!preRasterized,
|
||||
imageDimensions =
|
||||
FirstCase[
|
||||
Quiet[ImportByteArray[byteArrayResult, {"PNG", "Options"}]],
|
||||
Verbatim[Rule]["ImageSize", {width_?IntegerQ, height_?IntegerQ}] :>
|
||||
(ToString /@
|
||||
IntegerPart[
|
||||
{width, height}/72 *
|
||||
cssResolutionDPI *
|
||||
(* also, reduce the size of the image somewhat *) 4/5
|
||||
]),
|
||||
$Failed
|
||||
];
|
||||
If[
|
||||
FailureQ[imageDimensions],
|
||||
Return[{$Failed, $Failed}];
|
||||
];
|
||||
];
|
||||
|
||||
(* return byteArrayResult and imageDimensions *)
|
||||
Return[{byteArrayResult, imageDimensions}];
|
||||
];
|
||||
|
||||
(* generate HTML for the rasterized form of a result *)
|
||||
@ -265,11 +328,13 @@ If[
|
||||
(* the rasterization of result *)
|
||||
imageData,
|
||||
(* the rasterization of result in base 64 *)
|
||||
imageDataInBase64
|
||||
imageDataInBase64,
|
||||
(* the dimensions of the image *)
|
||||
imageDimensions
|
||||
},
|
||||
|
||||
(* rasterize the result *)
|
||||
imageData =
|
||||
{imageData, imageDimensions} =
|
||||
toImageData[
|
||||
$trueFormatType[result]
|
||||
];
|
||||
@ -279,7 +344,7 @@ If[
|
||||
imageInBase64 = BaseEncode[imageData];
|
||||
,
|
||||
(* if the rasterization did fail, try to rasterize result with Shallow *)
|
||||
imageData =
|
||||
{imageData, imageDimensions} =
|
||||
toImageData[
|
||||
$trueFormatType[Shallow[result]]
|
||||
];
|
||||
@ -289,7 +354,7 @@ If[
|
||||
imageInBase64 = BaseEncode[imageData];
|
||||
,
|
||||
(* if the rasterization did fail, try to rasterize $Failed *)
|
||||
imageData =
|
||||
{imageData, imageDimensions} =
|
||||
toImageData[
|
||||
$trueFormatType[$Failed]
|
||||
];
|
||||
@ -308,8 +373,15 @@ If[
|
||||
Return[
|
||||
StringJoin[
|
||||
(* display a inlined PNG image encoded in base64 *)
|
||||
"<img alt=\"Output\" src=\"data:image/png;base64,",
|
||||
(* the rasterized form of the result, converted to base64 *)
|
||||
"<img ",
|
||||
(* provide the image dimensions to use *)
|
||||
If[
|
||||
!FailureQ[imageDimensions],
|
||||
{"width=\"", First[imageDimensions], "\" height=\"", Last[imageDimensions], "\" "},
|
||||
{}
|
||||
],
|
||||
(* provide the rasterized form of the result, converted to base64, and other information *)
|
||||
"alt=\"Output\" src=\"data:image/png;base64,",
|
||||
imageInBase64,
|
||||
(* end the element *)
|
||||
"\">"
|
||||
|
@ -187,7 +187,7 @@ If[
|
||||
(* otherwise, use a function that converts the output to an image *)
|
||||
If[AllTrue[totalResult["EvaluationResult"], textQ],
|
||||
toOut = toOutText,
|
||||
toOut = toOutImage
|
||||
toOut = UsingFrontEnd @* toOutImage
|
||||
];
|
||||
(* prepare the content for a reply message frame to be sent on the IO Publish socket *)
|
||||
ioPubReplyContent = ExportString[
|
||||
|
Loading…
x
Reference in New Issue
Block a user