2016-08-07 6 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 밖으로 엿되는 부분입니다) 지금까지 내 작품 --------- 아래의 해결 방법 -------

처음에는 업로드 한 이미지를 중간 색으로 워터 마킹하여 내 푸른 색 저장소로 전송했습니다. 나는 정말로 가까웠다 고 생각하지만, 나는 다른 모든 것들과 함께 일할 수는 없었다. 업로드 한 이미지는 한 번에 하나씩 올리며 < 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을 FromStream으로 대체하고 있습니다. 당신의 제안을 조사 할 것입니다. 나는이 수업들과 함께 자주 일하지 않으므로 조금은 장애물이되어 버렸다. –

+0

불완전한 코드에 사과드립니다. 목표는 최종 사용자가 이미지 애셋을 내 앱에 업로드 할 때 하늘에 저장하는 것입니다. 간단히 이미지 애셋의 오른쪽 상단에 내 브랜드 로고 16x16 PNG를 배치하고 싶습니다. blob.UploadFromStream 메서드를 호출하면 저장 컨테이너에 스트리밍 할 준비가되었습니다. –

답변

3

대상에 이미지를 그리면 이미지에 워터 마크를 넣을 수 있습니다. TextureBrush은 대상 전체에 이미지를 바둑판 식으로 배열합니다.

// 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

장미 빛 이미지가 노출 된 워터 마크 이미지, 다른 : 당신이 원하는 크기로 썸네일 수 있기 때문에

큰 워터 마크 이미지 (최대 125x125)하지만 나던 물질을 사용하고 있습니다 최종 결과입니다. TexturedBrush 사용 워터 마크와 같은 낮은 불투명도와 함께 사용 타일, 각도 텍스트 등의 작업을 수행 할 수 있습니다하십시오 TextureBrush을 만들 때 가끔 오류를 얻을 수 있습니다

enter image description here

, 나는 크기를 지정하여 그것을 피할 :

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

나는 내가 원하는만큼 우아하지 않고 지금 가고있는 것을 올렸지 만 그것은 일을한다. 내 작업 코드가 환영받을 것입니다. 그렇지 않으면 다시 도움을 청합니다! –

관련 문제