2016-08-07 35 views
1

ユーザーからの画像ファイルのアップロードを受け入れ、コーナーに小さな16x16アイコンを書き込んで、Azureクラウドストレージに保存します。アップロードした画像にウォーターマーク画像を書き込む(MVCコントローラ内)

私はこのトピックに関するいくつかの良い記事を見つけましたが、私はそれを得ていません。私はほとんどそれを持っていたと思ったが、TextureBrushラインでOutOfMemory例外が出ていた。

追加する必要がある追加情報がある場合はお知らせください。何か助けていただきありがとうございます。 ----------

public Stream AddWaterMark(Stream stream) 
    { 

     var bytes = Convert.FromBase64String(Settings.Default.PartnifyWatermark); 
     Image watermarkImage; 
     using (var ms = new MemoryStream(bytes)) 
     { 
      watermarkImage = Image.FromStream(ms); 
     } 


     using (var image = Image.FromStream(stream)) 
     using (var imageGraphics = Graphics.FromImage(image)) 
     using (var watermarkBrush = new TextureBrush(watermarkImage)) 
     { 
      var x = (image.Width - 16); 
      var y = (image.Height - 16); 
      watermarkBrush.TranslateTransform(x, y); 
      imageGraphics.FillRectangle(watermarkBrush, new Rectangle(new Point(x, y), new Size(watermarkImage.Width + 1, watermarkImage.Height))); 
      image.Save(stream, ImageFormat.Png); 
      return stream; 
     } 

    } 

   // add watermark before uploading to cloud server 
       Stream stream = _fileManager.AddWaterMark(file.InputStream); 

       cloudBlockBlob.UploadFromStream(stream, null, null, null); 
       fileUrl = cloudBlockBlob.Uri.ToString(); 
--------<snip>---------- 

そして、私は、addwatermark方法:

はここ(は、addwatermarkが出crappingされる部分である)これまでの私の仕事です---------下の解決策-------

最初に私のアップロードされたイメージをミッドストリームに透かし入れてから、私の紺碧の記憶装置に送信したかったのです。私は本当に近くにいると思うが、他のすべてのものと一緒に働くことはできない。私のアップロードされた画像は一度に1つずつ来て、< 2Mなので、画像を保存してスタンプし、続けていくという解決策に移りました。

注:最初のカップルラインがちょうどそれを引き出しているので、私はアプリケーションの設定にbase64文字列として会社の透かしを入れました。復帰後、呼び出しメソッドは単にクローンをつかみ、アップロードし、クローンを削除します。明らかに画像を扱うためのいくつかのよりエレガントな方法がありますが、マーキングを示すためにはこれが受け入れられます。私はこのアプローチについては好きではありません

public void AddWaterMark(string filepath) 
    { 
     //var outStream = new MemoryStream(); 
     var watermarkImageBase64 = Settings.Default.CompanyWatermark; 
     var data = Convert.FromBase64String(watermarkImageBase64); 
     using (var streamWatermark = new MemoryStream(data, 0, data.Length)) 
     using (var watermark = Image.FromStream(streamWatermark)) 
     using (var targetImage = Image.FromFile(filepath)) 
     using (var g = Graphics.FromImage(targetImage)) 
     { 
      var destX = (targetImage.Width - watermark.Width) - 10; 
      var destY = 10; 

      g.DrawImage(watermark, new Rectangle(destX, destY, watermark.Width, watermark.Height)); 

      using (var cloneImage = (Image) targetImage.Clone()) 
      { 
       cloneImage.Save(Server.MapPath("~/User_Data/cloneImage.png")); 
      } 
     } 

ことの一つは、....、着信画像はすでに透かしポイントでPNG形式に変換されますが、透かしは16×16で、対象画像の大きさに応じて、小さくても大きく表示されます。ターゲット画像の解像度が何であれ、同じサイズの周りに「出現する」ことを好むでしょう。

+0

透かし画像がPNGの場合、TextureBrushは必要ありません。ちょうど角に描きます。 – Plutonix

+0

私は多くの記憶があるので、例外は誤解を招くと思います。早すぎる処分や読み込み前に画像を使用しようとすると、これが起こる可能性があります。私のbase64文字列が何らかの形で正しくないか破損している場合は、現在FromStreamをFromFileに置き換えています。あなたの提案を調べます。私はこれらのクラスでは非常に頻繁に作業しないので、ちょっとしたハードルでした。 –

+0

不完全なコードに対するお詫び。目標はこれです:私のエンドユーザが画像アセットを私のアプリにアップロードすると、彼らは紺色に保存されます。私は、イメージアセットの右上隅にブランドロゴの16x16 PNGを配置したいだけです。 blob.UploadFromStreamメソッドを呼び出すと、そのストリームを描画してストレージコンテナにストリームする準備ができている必要があります。 –

答えて

3

イメージをターゲットに描画すると、イメージにウォーターマークを付けることができます。 TextureBrushは、ターゲット全体に画像を並べ替える作業を行います。

これは、あなたが希望のサイズにそれをサムネイル可能性があるため、大きな透かし画像(125×125)が、そのdoesntの物質を使用している:

// show before 
pbWM.Image = Image.FromFile(@"C:\Temp\horus_w.png"); 

using (Image watermark = Image.FromFile(@"C:\Temp\horus_w.png")) 
using (Image TargetImg = Image.FromFile(@"C:\Temp\BigHead.jpg")) 
using (Graphics g = Graphics.FromImage(TargetImg)) 
{ 
    var destX = (TargetImg.Width - watermark.Width) - 10; 
    var destY = (TargetImg.Height - watermark.Height) - 10; 

    g.DrawImage(watermark, new Rectangle(destX, 
       destY, 
       watermark.Width, 
       watermark.Height)); 
    // display a clone for demo purposes 
    pb2.Image = (Image)TargetImg.Clone(); 
} 

enter image description here

バラ色の画像は、他の、裸の透かし画像です最終結果です。 TexturedBrush使用あなたは、透かしのような低不透明で使用するタイル張り、斜めのテキストのようなものを行うことができます。TextureBrushを作成するときは、時々そのエラーを取得することができます

​​

、私はサイズを指定することで、それを避ける:

using (TextureBrush br = new TextureBrush(wmImg, 
      new Rectangle(0, 0, wmImg.Width - 1, wmImg.Height - 1))) 
{ 
    g.FillRectangle(br, 0, 0, Marked.Width, Marked.Height); 
} 

透かし画像とロゴが同じ場合は、変数に格納して同じ画像を何度も繰り返し使用します。問題のコードは、毎回新しいwatermarkImageを作成し、それを廃棄しません。

+1

ニース、私たちの簡単な交換は私に覚えておくべきいくつかの重要なヒントを教えてくれました。私は本当にあなたの反応に感謝しています...時間は貴重なので、あなたのいくつかを貸してくれてありがとう.. –

+0

私は今私が行っているものを投稿しました、私が欲しいほど優雅ではなく、仕事をします...私の作業コードは歓迎されるでしょう。 –

関連する問題