문제

이미지를 동적으로 생성해야하며 튜토리얼을 읽은 후 여기 WPF의 모든 컨트롤과 레이아웃을 사용하여 렌더링을 생성 한 다음 JPG로 저장할 수 있다는 것을 알고 있습니다. 아이디어는 gdi+대신 이것을 사용하는 것입니다.

문제는 프로그래밍 방식으로 WPF 캔버스를 생성하는 일반 DLL 파일을 만드는 방법입니다. 그러면 컨트롤을 추가 한 다음 이미지 파일에 제공 할 수 있습니다. ASP.NET 응용 프로그램에 의해 소비 될 것임을 명심하십시오.

누군가 아이디어가 있습니까?

도움이 되었습니까?

해결책

그 예는 좋은 출발을 가지고 있지만 그와 함께 불필요한 쓰레기가 많이 있다는 것을 알았습니다. 가장 중요한 것은 별도의 WPF 프로젝트가 필요하지 않다는 것입니다.

다음은해야 할 일입니다.

  • 웹 프로젝트의 참조 프레젠테이션 코어, 프레젠테이션 프레임 워크 및 Windowsbase.
  • STA 스레드에서 프로그래밍 방식으로 캔버스 및 기타 WPF 객체를 만듭니다.
  • WPF 앱의 컨텍스트 외부에서 업데이트되도록 몇 가지 특별한 방법을 호출하십시오.
  • rendertargetbitmap을 사용하여 이미지로 렌더링하십시오.
  • 스레드의 디스패처를 종료하십시오.
  • 마임 유형을 설정하고 ASP.NET으로 이미지를 출력하십시오.

이것을보다 효율적으로 만들려면 각 이미지마다 새 스레드를 만들지 않고 동일한 스레드를 재사용 할 수 있습니다. 이 경우 스레드를 종료 할 때만 디스패처를 정리하면됩니다.

다음은 내가 가진 전체 작업 코드입니다.

using System;
using System.Web;
using System.Threading;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Documents;

public partial class _Default : System.Web.UI.Page
{
    private byte[] imageBuffer;

    public void Page_Load(object sender, EventArgs e)
    {
        this.RenderImage();

        Response.Clear();
        Response.ContentType = @"image/png";
        Response.BufferOutput = true;
        Response.BinaryWrite(this.imageBuffer);
        Response.Flush();
    }

    public void RenderImage()
    {
        Thread worker = new Thread(new ThreadStart(this.RenderImageWorker));
        worker.SetApartmentState(ApartmentState.STA);
        worker.Name = "RenderImageWorker";
        worker.Start();
        worker.Join();
    }

    public void RenderImageWorker()
    {
        Canvas imageCanvas = new Canvas { Width = 600, Height = 200, Background = Brushes.Azure };

        TextBlock tb = new TextBlock();
        tb.Width = (double)400;
        //tb.Height = (double)200;
        tb.TextAlignment = TextAlignment.Center;
        tb.Inlines.Add(new Run("This is "));
        tb.Inlines.Add(new Bold(new Run("bold")));
        tb.Inlines.Add(new Run(" text."));
        tb.FontSize = 30;
        tb.Foreground = Brushes.Blue;

        imageCanvas.Children.Add(tb);

        // Update layout
        imageCanvas.Measure(new Size(imageCanvas.Width, imageCanvas.Height));
        imageCanvas.Arrange(new Rect(new Size(imageCanvas.Width, imageCanvas.Height)));

        RenderTargetBitmap bitmapRenderer = new RenderTargetBitmap((int)imageCanvas.ActualWidth, (int)imageCanvas.ActualHeight, 96, 96, PixelFormats.Pbgra32);
        bitmapRenderer.Render(imageCanvas);

        PngBitmapEncoder png = new PngBitmapEncoder();
        png.Frames.Add(BitmapFrame.Create(bitmapRenderer));

        using (MemoryStream memoryStream = new MemoryStream())
        {
            png.Save(memoryStream);
            this.imageBuffer = memoryStream.ToArray();
        }

        if (bitmapRenderer.Dispatcher.Thread.IsAlive)
        {
            bitmapRenderer.Dispatcher.InvokeShutdown();
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top