将大 WPF 画布切成许多小 PNG 图像

发布于 2024-10-07 18:26:55 字数 97 浏览 1 评论 0原文

假设我有非常大的 (3000 X 4000) WPF 画布。

我正在寻找将此画布切成一堆 n × n .png 图像图块的最佳方法。

有什么建议吗?

Assume I have very large (3000 X 4000) WPF canvas.

I'm looking for the best way to slice this canvas into a bunch of n by n .png image tiles.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼藏柔 2024-10-14 18:26:55

不确定最好还是最简单,但这是一种方法:)

private void SaveFrameworkElement(FrameworkElement frameworkElement)
{
    BitmapImage bitmapImage = VisualToBitmapImage(frameworkElement);
    for (int startX = 0; startX <= 400; startX += 100)
    {
        for (int startY = 0; startY <= 100; startY += 100)
        {
            SaveImage(bitmapImage, startX, startY, 100, 100, "C:\\CutImage_" + startX.ToString() + "-" + startY.ToString() + ".png");
        }
    }
}

public BitmapImage VisualToBitmapImage(FrameworkElement frameworkElement)
{
    RenderTargetBitmap rtb = new RenderTargetBitmap((int)frameworkElement.ActualWidth,
                                                    (int)frameworkElement.ActualHeight,
                                                    96d,
                                                    96d,
                                                    PixelFormats.Default);
    rtb.Render(frameworkElement);

    MemoryStream stream = new MemoryStream();
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(rtb));
    encoder.Save(stream);

    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.BeginInit();
    bitmapImage.StreamSource = stream;
    bitmapImage.EndInit();

    return bitmapImage;            
}
public void SaveImage(BitmapImage sourceImage,
                      int startX,
                      int startY,
                      int width,
                      int height,
                      string filePath)
{
    TransformGroup transformGroup = new TransformGroup();
    TranslateTransform translateTransform = new TranslateTransform();
    translateTransform.X = -startX;
    translateTransform.Y = -startY;
    transformGroup.Children.Add(translateTransform);

    DrawingVisual vis = new DrawingVisual();
    DrawingContext cont = vis.RenderOpen();
    cont.PushTransform(transformGroup);
    cont.DrawImage(sourceImage, new Rect(new Size(sourceImage.PixelWidth, sourceImage.PixelHeight)));
    cont.Close();

    RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Default);
    rtb.Render(vis);

    FileStream stream = new FileStream(filePath, FileMode.Create);
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(rtb));
    encoder.Save(stream);
    stream.Close();
}

Not sure about either best or easiest but here's a way :)

private void SaveFrameworkElement(FrameworkElement frameworkElement)
{
    BitmapImage bitmapImage = VisualToBitmapImage(frameworkElement);
    for (int startX = 0; startX <= 400; startX += 100)
    {
        for (int startY = 0; startY <= 100; startY += 100)
        {
            SaveImage(bitmapImage, startX, startY, 100, 100, "C:\\CutImage_" + startX.ToString() + "-" + startY.ToString() + ".png");
        }
    }
}

public BitmapImage VisualToBitmapImage(FrameworkElement frameworkElement)
{
    RenderTargetBitmap rtb = new RenderTargetBitmap((int)frameworkElement.ActualWidth,
                                                    (int)frameworkElement.ActualHeight,
                                                    96d,
                                                    96d,
                                                    PixelFormats.Default);
    rtb.Render(frameworkElement);

    MemoryStream stream = new MemoryStream();
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(rtb));
    encoder.Save(stream);

    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.BeginInit();
    bitmapImage.StreamSource = stream;
    bitmapImage.EndInit();

    return bitmapImage;            
}
public void SaveImage(BitmapImage sourceImage,
                      int startX,
                      int startY,
                      int width,
                      int height,
                      string filePath)
{
    TransformGroup transformGroup = new TransformGroup();
    TranslateTransform translateTransform = new TranslateTransform();
    translateTransform.X = -startX;
    translateTransform.Y = -startY;
    transformGroup.Children.Add(translateTransform);

    DrawingVisual vis = new DrawingVisual();
    DrawingContext cont = vis.RenderOpen();
    cont.PushTransform(transformGroup);
    cont.DrawImage(sourceImage, new Rect(new Size(sourceImage.PixelWidth, sourceImage.PixelHeight)));
    cont.Close();

    RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Default);
    rtb.Render(vis);

    FileStream stream = new FileStream(filePath, FileMode.Create);
    PngBitmapEncoder encoder = new PngBitmapEncoder();
    encoder.Frames.Add(BitmapFrame.Create(rtb));
    encoder.Save(stream);
    stream.Close();
}
落花浅忆 2024-10-14 18:26:55

你可以做这样的事情(不是我的代码,取自msdnsocial):

public static RenderTargetBitmap GetJpgImage(UIElement targetUIElement, double scale, int quality)
{
double actualHeight = targetUIElement.RenderSize.Height;
double actualWidth = targetUIElement.RenderSize.Width;

double renderedHeight = actualHeight * scale;
double renderedWidth = actualWidth * scale;

RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderedWidth, (int)renderedHeight, 96, 96, PixelFormats.Pbgra32);
VisualBrush sourceBrush = new VisualBrush(targetUIElement);

DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();

using (drawingContext)
{
    drawingContext.PushTransform(new ScaleTransform(scale, scale));
    drawingContext.DrawRectangle(sourceBrush, null, new Rect(new System.Windows.Point(0, 0), new System.Windows.Point(actualWidth, actualHeight)));
}
renderTarget.Render(drawingVisual);

JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
jpgEncoder.QualityLevel = quality;
jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
MemoryStream memoryStream = new MemoryStream();
jpgEncoder.Save(memoryStream);

File.WriteAllBytes(@"D:\a.jpg", memoryStream.ToArray());

return renderTarget;
}

详细说明该代码以将JPG分成正方形,然后你可以使用网格,以编程方式创建一堆列和行,并使用网格。 Row 和 Grid.Column 以编程方式在图像上附加属性,以指定存在哪些(切片)图像。

You can do something like this (not my code, taken from msdn social):

public static RenderTargetBitmap GetJpgImage(UIElement targetUIElement, double scale, int quality)
{
double actualHeight = targetUIElement.RenderSize.Height;
double actualWidth = targetUIElement.RenderSize.Width;

double renderedHeight = actualHeight * scale;
double renderedWidth = actualWidth * scale;

RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderedWidth, (int)renderedHeight, 96, 96, PixelFormats.Pbgra32);
VisualBrush sourceBrush = new VisualBrush(targetUIElement);

DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();

using (drawingContext)
{
    drawingContext.PushTransform(new ScaleTransform(scale, scale));
    drawingContext.DrawRectangle(sourceBrush, null, new Rect(new System.Windows.Point(0, 0), new System.Windows.Point(actualWidth, actualHeight)));
}
renderTarget.Render(drawingVisual);

JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
jpgEncoder.QualityLevel = quality;
jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
MemoryStream memoryStream = new MemoryStream();
jpgEncoder.Save(memoryStream);

File.WriteAllBytes(@"D:\a.jpg", memoryStream.ToArray());

return renderTarget;
}

Elaborate on that code to section the JPG off into squares, then you can use a Grid, programmatically creating a bunch of columns and rows, and using the Grid.Row and Grid.Column attached properties on the images programmatically to specify which (sliced) images are present.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文