You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP Win2D应用中按比例调整图像大小的问题

Hey there, let's fix that stretching issue with your Win2D CanvasAnimatedControl! The problem here is that when you call DrawImage(_bitmap) directly, it stretches the image to fill the entire control bounds regardless of its original aspect ratio. Same goes for the text—without accounting for the control's resized dimensions relative to your content's natural size, it'll get warped too.

Fixing Aspect Ratio Preservation in Win2D CanvasAnimatedControl

Step 1: Calculate Aspect Ratio & Target Drawing Bounds

First, we need to compare your bitmap's original aspect ratio to the control's current aspect ratio. This lets us calculate a scaled, non-stretched rectangle that fits neatly within the control (with optional letterbox/pillarbox bars if needed).

Update your Draw method with this logic:

private void Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
{
    if (!IsLoadInProgress())
    {
        // Get aspect ratios for the image and current control size
        float imageAspectRatio = _bitmap.Size.Width / _bitmap.Size.Height;
        float controlAspectRatio = sender.Size.Width / sender.Size.Height;

        float scale;
        float xOffset = 0;
        float yOffset = 0;

        // Determine scaling factor and offsets to maintain proportionality
        if (controlAspectRatio > imageAspectRatio)
        {
            // Control is wider than the image—add pillarbox bars left/right
            scale = sender.Size.Height / _bitmap.Size.Height;
            xOffset = (sender.Size.Width - (_bitmap.Size.Width * scale)) / 2;
        }
        else
        {
            // Control is taller than the image—add letterbox bars top/bottom
            scale = sender.Size.Width / _bitmap.Size.Width;
            yOffset = (sender.Size.Height - (_bitmap.Size.Height * scale)) / 2;
        }

        // Create the scaled, non-stretched drawing rectangle
        Rect drawRect = new Rect(xOffset, yOffset, _bitmap.Size.Width * scale, _bitmap.Size.Height * scale);

        // Draw the image to this safe rectangle
        args.DrawingSession.DrawImage(_bitmap, drawRect);

        // Pass the scaled bounds to your text drawing method
        DrawText(args, drawRect, "...TESTING TEXT...");
    }
}

Step 2: Adjust Text to Match Scaled Content

Modify your DrawText method to use the scaled bounds, so text scales proportionally with the image and stays properly aligned:

private void DrawText(CanvasAnimatedDrawEventArgs args, Rect drawRect, string text)
{
    // Scale text size relative to the image's scaling factor
    float scaledTextSize = 24 * (drawRect.Width / _bitmap.Size.Width);

    // Center text over the scaled image (adjust positioning as needed)
    args.DrawingSession.DrawText(
        text,
        drawRect.X + (drawRect.Width / 2),
        drawRect.Y + (drawRect.Height / 2),
        Colors.Black,
        new CanvasTextFormat
        {
            FontSize = scaledTextSize,
            HorizontalAlignment = CanvasHorizontalAlignment.Center,
            VerticalAlignment = CanvasVerticalAlignment.Center
        });
}

Optional: Add DPI Scaling for Crisper Rendering

If you want sharp content across different display DPIs, factor in the control's DPI value when calculating sizes:

float dpi = sender.Dpi;
// Adjust bitmap size to account for DPI
float dpiAdjustedImageWidth = _bitmap.Size.Width * dpi / 96;
float dpiAdjustedImageHeight = _bitmap.Size.Height * dpi / 96;
float imageAspectRatio = dpiAdjustedImageWidth / dpiAdjustedImageHeight;
// Rest of the scaling logic remains similar

Why This Works

By calculating a uniform scaling factor based on aspect ratios, we ensure the image never gets stretched—only scaled up/down proportionally. The text uses the same scaling factor to maintain its relative size to the image, and positioning it based on the scaled image bounds keeps everything aligned correctly.

内容的提问来源于stack exchange,提问作者Maximus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:27:51