注意:你可以通过这里获取一个现成的带有此功能的调色板。
Arnoud的解决方案令我兴奋不已,但也让我不耐烦,所以我做了一些改进。没有他的代码学习,我是无法完成这个版本的。这个版本似乎更加可靠,并且更少出现超时错误,但老实说,我对Java一无所知,欢迎提出任何改进意见。
最重要的是:这个版本直接上传到stack.imgur.com
,因此在StackOverflow上使用是安全的,而不必担心上传的图片会在一段时间后消失。
我提供了三个功能:
stackImage
上传表达式(导出为PNG格式),并返回URL
stackMarkdown
返回准备好复制的markdown
stackCopyMarkdown
将markdown复制到剪贴板
下一步是创建一个调色板按钮,在笔记本中自动执行此操作以选定图形。非常欢迎对代码进行改进。
Needs["JLink`"]
stackImage::httperr = "Server returned respose code: `1`";
stackImage::err = "Server returner error: `1`";
stackImage[g_] :=
Module[
{getVal, url, client, method, data, partSource, part, entity, code,
response, error, result},
(* this function attempts to parse the response fro the SO server *)
getVal[res_, key_String] :=
With[{k = "var " <> key <> " = "},
StringTrim[
First@StringCases[First@Select[res, StringMatchQ[#, k ~~ ___] &],
k ~~ v___ ~~ ";" :> v],
"'"]
];
data = ExportString[g, "PNG"];
JavaBlock[
url = "https://stackoverflow.com/upload/image";
client = JavaNew["org.apache.commons.httpclient.HttpClient"];
method = JavaNew["org.apache.commons.httpclient.methods.PostMethod", url];
partSource = JavaNew["org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource", "mmagraphics.png", MakeJavaObject[data]@toCharArray[]];
part = JavaNew["org.apache.commons.httpclient.methods.multipart.FilePart", "name", partSource];
part@setContentType["image/png"];
entity = JavaNew["org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity", {part}, method@getParams[]];
method@setRequestEntity[entity];
code = client@executeMethod[method];
response = method@getResponseBodyAsString[];
]
If[code =!= 200, Message[stackImage::httperr, code]; Return[$Failed]];
response = StringTrim /@ StringSplit[response, "\n"];
error = getVal[response, "error"];
result = getVal[response, "result"];
If[StringMatchQ[result, "http*"],
result,
Message[stackImage::err, error]; $Failed]
]
stackMarkdown[g_] := "![Mathematica graphics](" <> stackImage[g] <> ")"
stackCopyMarkdown[g_] := Module[{nb, markdown},
markdown = Check[stackMarkdown[g], $Failed];
If[markdown =!= $Failed,
nb = NotebookCreate[Visible -> False];
NotebookWrite[nb, Cell[markdown, "Text"]];
SelectionMove[nb, All, Notebook];
FrontEndTokenExecute[nb, "Copy"];
NotebookClose[nb];
]
]
更新:
这里有一个按钮,可以显示所选内容的预览,并提供上传(或取消)选项。但需要先定义之前的函数。
Button["Upload to SO",
Module[{cell = NotebookRead@InputNotebook[], img},
If[cell =!= {}, img = Rasterize[cell];
MessageDialog[
Column[{"Upload image to StackExchange sites?",
img}], {"Upload and copy MarkDown" :> stackCopyMarkdown[img],
"Cancel" :> Null}, WindowTitle -> "Upload to StackExchange"]]]]
很遗憾,我无法将按钮放在调色板(CreatePalette
)中,因为调色板的尺寸会影响光栅化。欢迎提出解决此问题的方案。
更新2:
根据这个问题的答案,在Windows系统下可使用下面的代码实现调色板按钮:
button = Button["Upload to SO",
Module[{sel},
FrontEndExecute[
FrontEndToken[FrontEnd`SelectedNotebook[], "CopySpecial", "MGF"]];
sel = Cases[NotebookGet@ClipboardNotebook[],
RasterBox[data_, ___] :>
Image[data, "Byte", ColorSpace -> "RGB", Magnification -> 1],
Infinity];
If[sel =!= {},
With[{img = First[sel]},
MessageDialog[
Column[{"Upload image to StackExchange sites?",
img}], {"Upload and copy MarkDown" :> stackCopyMarkdown[img],
"Cancel" :> Null}, WindowTitle -> "Upload to StackExchange"]
]
]
]
]
CreatePalette[button]
警告:即使您在预览框中点击取消,它也会破坏剪贴板内容。
http://i.stack.imgur.com/
更加困难(您需要“驱动”SO界面)。 - Dr. belisariusimgur[g]
,并复制和粘贴Markdown文本。在努力方面似乎真的没有太大的区别。 - Sjoerd C. de Vriesstack.imgur.com
。请参见这里:http://stackapps.com/questions/2664/is-there-an-api-to-upload-images-to-ses-imgur-installation/2667#2667 - Szabolcs