2011-11-07 8 views
52

mathematicaタグフォロワーすべてに挑戦しています。 imgurアップローダを作成してMathematicaのSOの投稿に画像を挿入するほうがずっと便利です。MathematicaからImgurに画像をアップロード

引数をラスタライズする(最終サイズがStackOverflow投稿の幅よりも広くないことを確認してください)、PNGに変換してimgurにアップロードし、すぐに戻ることができる関数imgur[g_]を作成するにはどうすればよいですか? ![Mathematica graphic](http://i.imgur.com/ZENa4.jpg)などのMarkDown行を貼り付けましたか?

有用な参考文献:ragfield

  • Example of using POST requests from Mathematica on SO (uploading to ifile.it)
  • によって

    +2

    「http:// i.stack.imgur.com /」へのアップロードが難しいことに注意してください(SOインターフェースを「駆動」する必要があります)。 –

    +0

    @belisariusおっと、私はそのことを知らなかったStackOverflow別のimgurサイトを使用しています... imgurのメインのサイトでは、画像は永遠に保存されない可能性がありますので、おそらくSOのために使用することはお勧めできませんhttp://imgur.com/faq#long(少なくとも1つのビュー/それらが保たれるためには6ヶ月が必要です) – Szabolcs

    +4

    手作業でグラフィックスを投稿することはそれほど難しくありません(V8)。グラフィックを右クリックし、 "Save Image as ..."を選択します。次に、ファイルダイアログボックスが最後に開いた場所です。これは通常、output.pngというファイルが次のインカネーションで上書きされるのを待っているデスクトップです。 2回のクリックはすべて、2回以上のクリックは私の答えのボックスに掲載されます。たった15秒かかります。 Markdownラインを取得して貼り付けると、ほぼ同じ時間がかかります。 –

    答えて

    16

    小鳥はちょうどこの質問へMathematicaの溶液(基礎となる実装はまだJLINKを使用しますが、この答えはすべてのJava関連のコードを隠して)を私に知らせ:

    imgur[expr_] := Module[ 
    {url, key, image, data, xml, imgurUrl}, 
    url = "http://api.imgur.com/2/upload"; 
    key = "c07bc3fb59ef878d5e23a0c4972fbb29"; 
    image = Fold[ExportString, expr, {"PNG", "Base64"}]; 
    xml = Import[url, 
        "XML", "RequestMethod" -> "POST", 
        "RequestParameters" -> {"key" -> key, "image" -> image}]; 
    imgurUrl = Cases[xml, XMLElement["original", {}, {string_}] :> string, 
        Infinity][[1]]; 
    "![Mathematica graphic](" <> imgurUrl <> ")" 
    ] 
    

    これはV8のみで、 XMLインポートオプション"RequestMethod"および"RequestParameters"は文書化されておらず、実験的です(したがって変更される可能性があります)。

    +0

    このArnoudを共有してくれてありがとう!残念ながら、これはStackOverflowにアップロードしようとしているときには動作していないようです(他の回答のコメントで述べた方法を使用してください)。私は問題は、画像を[multipart/form-data](http://en.wikipedia.org/wiki/Multipart/form-data#Form_Data)として提出する必要があると思います。これを行う方法は分かりますか?また、これをプレビューした後に選択肢をアップロードするパレットボタンにする方法についてのアイデアはありますか?私が試したことと動作しなかったことについての私の他の答えを見てください(あまりにも狭いパレット幅がラスタライズに使用されます)。 – Szabolcs

    +0

    +1:とてもいいです!今私はOAuthでこれを動作させようとしているので、自分のアカウントのアルバムなどに画像を直接アップロードできます:)また、それらの文書化されていないオプションをどのように見つけましたか? – nixeagle

    +0

    @nixeagleもしあなたがそれを働かせたら、ここに追加の答えとしてあなたがコードを掲示すれば(挑戦の説明とあなたの解決方法を書いていれば)気にしません。 – Szabolcs

    12

    注::これは、匿名のキーで匿名のimgurアップローダを使用しています。 imgurサイトはアップロードを50アップロード/時間に制限していますが、通常はこれで問題ありませんが、多くの人がこれを同時に試してみると問題が発生する可能性があります。だからここにあなた自身の匿名のキーを取得してください:

    http://imgur.com/register/api_anon

    をそしてあなた自身のキー(感謝!)で、以下のコードで鍵を交換してください。

    コードの最も難しい部分は、Mathematica表現からPNG画像への変換から、Base64エンコーディングからURLエンコーディングへの変換でした。間違って行う方法は約1,000通りあり、私はそれをすべて試してみることができます。

    コードはいくつかの作品に分解:

    • POSTのURL
    • がHTTP接続
    • を作る構築
    • POSTのURLを送るXML
    • ある結果を、バック読みます
    • XMLからimgur URLを抽出する
    • imgur urlをマークダウン形式(またはMathematicaHyperlink機能)。ここで

    コードは次のとおりです。

    imgur[expr_] := 
    Module[{url, key, image, data, jUrl, jConn, jWriter, jInput, buffer, 
        byte, xml, imgurUrl}, 
        Needs["JLink`"]; 
        JLink`JavaBlock[ 
        JLink`LoadJavaClass["java.net.URLEncoder"]; 
        url = "http://api.imgur.com/2/upload"; 
        key = "c07bc3fb59ef878d5e23a0c4972fbb29"; 
        image = ExportString[ExportString[expr, "PNG"], "Base64"]; 
        data = 
        URLEncoder`encode["key" , "UTF-8"] <> "=" <> 
        URLEncoder`encode[ key , "UTF-8"] <> "&" <> 
        URLEncoder`encode["image" , "UTF-8"] <> "=" <> 
        URLEncoder`encode[ image , "UTF-8"] ; 
        jUrl = JLink`JavaNew["java.net.URL", url]; 
        jConn = [email protected][]; 
        [email protected][True]; 
        jWriter = 
        JLink`JavaNew["java.io.OutputStreamWriter", 
        [email protected][]]; 
        [email protected][data]; 
        [email protected][]; 
        jInput = [email protected][]; 
        buffer = {}; 
        While[(byte = [email protected][]; byte >= 0), AppendTo[buffer, byte]]; 
        ]; 
        xml = ImportString[FromCharacterCode[buffer], "XML"]; 
        imgurUrl = 
        Cases[xml, 
        XMLElement["original", {}, {string_}] :> 
         string, \[Infinity]][[1]]; 
        "![Mathematica graphic](" <> imgurUrl <> ")" 
        ] 
    

    テスト:

    In[]:= g = Graphics[{Blue, Disk[]}, PlotRange -> 1.2, ImageSize -> Small]; 
         pic = Overlay[{Blur[[email protected], 10], g}]; 
         imgur[pic] 
    
    Out[]= ![Mathematica graphic](http://i.imgur.com/eGOlL.png) 
    

    そして、実際の画像:

    Mathematica graphic

    +0

    エンコードを行う方法はありますか? 'JLink'に頼らずにMathematica自体の中でアップロードしていますか? +1、btw。 – rcollyer

    +0

    @rcollyer - 私の知る限りではV8ではありません。あなたが見たいものをMathematicaの組み込み機能としてエンコードしてアップロードしていますか? –

    +1

    エラーが発生しました: '' Java :: excptn:Java例外が発生しました:java.io.IOException:サーバーがHTTP応答コードを返しました:URL:http://api.imgur.com/2/upload \t at sun .net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1290)。 XML'Parser'XMLGetString :: string:XML'Parser'XMLGetString [EndOfFile]の位置1で期待される文字列。 –

    13

    注:ゲット読みますこの機能を備えたy製パレットhere


    Arnoudのソリューションは私を興奮させ、辛抱強くしています。彼のコードを勉強しなければ、私はこれを行うことができませんでした。このバージョンはやや信頼性が高く、タイムアウトエラーが発生しにくいようですが、正直言ってJavaはまったく分かりませんので、改善が歓迎されています。

    このバージョンはstack.imgur.comに直接アップロードされるので、StackOverflowでここで使用すると安全です。しばらくするとアップロードされた画像が消えることを心配する必要はありません。

    私は、次の3つの機能を提供:

    • stackImageはPNGとしてエクスポート表現を、アップロードし、クリップボードへ
    • stackCopyMarkdownコピー値下げをコピーする準備ができて、URL
    • stackMarkdownが値下げを返しますが

    次の手順:選択したグラフィックに対して自動的にこれを行うパレットボタンを作成する電子ノート。コードの改善は大歓迎です。


    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[ 
        [email protected][[email protected][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]; 
        [email protected]["image/png"]; 
        entity = JavaNew["org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity", {part}, [email protected][]]; 
        [email protected][entity]; 
        code = [email protected][method]; 
        response = [email protected][]; 
        ] 
    
        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 = [email protected][], 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:

    button = Button["Upload to SO", 
        Module[{sel}, 
        FrontEndExecute[ 
        FrontEndToken[FrontEnd`SelectedNotebook[], "CopySpecial", "MGF"]]; 
        sel = Cases[[email protected][], 
        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] 
    

    警告:this questionへの回答に基づいて

    は、ここで働くWindows専用パレットボタンだ、それはあなたがキャンセル]をクリックしても、クリップボードの内容を破壊しますプレビューボックス。

    +0

    私は、ラスタライズパレットの問題は、独自の質問に値すると思います。 –

    +0

    それは素晴らしいです!私はこれを願って投票を予約していました。 *** + 1 *** –

    +1

    @ Mr.Wizardは、チャットルームでパッケージ化された解決策を確認します – Szabolcs

    関連する問題