我正在尝试重新调整Button控件的大小,同时保留原始图像的宽高比,这样新图像看起来不会被压扁/拉伸。
当我再次将其恢复到原始位置(正常窗口最大化状态)时,它应保持其原始分辨率。
基本上我希望所有显示器分辨率的图像看起来都一样。
例如:在我的申请中, 显示器分辨率 1280 * 1024(5:4)时,全球图像看起来很好 但看起来像椭圆一样伸展,显示器分辨率 1920×1080(16:9)
我知道我必须以编程方式进行某种形式的转换,但我不知道该怎么做。我尝试在OnResize事件上调用下面的方法,虽然它适用于第一次迭代,但随后调整大小时图像会变小,最后我最终丢失了我的图像。
public Rectangle MaintainAspectRatio(Image imgPhoto,Rectangle thumbRect) { int sourceWidth = imgPhoto.Width; int sourceHeight = imgPhoto.Height; int sourceX = 0; int sourceY = 0; int destX = 0; int destY = 0;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)thumbRect.Width / (float)sourceWidth);
nPercentH = ((float)thumbRect.Height / (float)sourceHeight);
//if we have to pad the height pad both the top and the bottom
//with the difference between the scaled height and the desired height
if (nPercentH < nPercentW)
{
nPercent = nPercentH;
destX = (int)((thumbRect.Width - (sourceWidth * nPercent)) / 2);
}
else
{
nPercent = nPercentW;
destY = (int)((thumbRect.Height - (sourceHeight * nPercent)) / 2);
}
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Rectangle retRect = new Rectangle(thumbRect.X, thumbRect.Y, destWidth, destHeight);
return retRect;
}
我在我的重写OnPaint事件处理程序方法中使用此代码:
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(E); 图形g = e.Graphics;
int iHeight;
int iWidth;
if (Image != null)
{
Rectangle ResizedRectangle = MaintainAspectRatio(Image,ClientRectangle);
iHeight = ResizedRectangle.Height;
iWidth = ResizedRectangle.Width;
}
else
{
iWidth = ClientRectangle.Width;
iHeight = ClientRectangle.Height;
}
// Draw border
Color oLeftTopColor = SystemColors.ControlLightLight;
Color oRightBottomColor = SystemColors.ActiveCaption;
Pen oLeftTopPen = new Pen(oLeftTopColor);
Pen oRightBottomPen = new Pen(oRightBottomColor);
// top line
g.DrawLine(oLeftTopPen, 0, 0, iWidth - 1, 0);
//g.DrawLine(new Pen(SystemColors.ControlLight), 1, 1, iWidth-2, 1);
// bottom line
g.DrawLine(oRightBottomPen, 0, iHeight, iWidth - 1, iHeight);
//g.DrawLine(new Pen(SystemColors.ControlDark), 1, iHeight-2, iWidth-2, iHeight-2);
// right line
g.DrawLine(oRightBottomPen, iWidth, 0, iWidth, iHeight - 1);
//g.DrawLine(new Pen(SystemColors.ControlDark), iWidth-2, 1, iWidth-2, iHeight-2);
// left line
g.DrawLine(oLeftTopPen, 0, 0, 0, iHeight - 1);
//g.DrawLine(new Pen(SystemColors.ControlLightLight), 1, 1, 1, iHeight-2);
// Draw image
if (Image != null)
{
Rectangle oDrawRectagle = new Rectangle(
0, 0, iWidth, iHeight);
if (Enabled == false)
{
e.Graphics.DrawImage(Image, oDrawRectagle,
0, 0, Image.Width, Image.Height,
GraphicsUnit.Pixel);
}
else
{
e.Graphics.DrawImage(Image, oDrawRectagle);
}
}
// Draw text
if (Text != null)
{
int iTextTop = 5;
int iTextLeft = 5;
int iMaxTextWidth = iWidth - 10;
int iMaxTextHeight = iHeight - 10;
}
}
任何人都可以指导我如何处理这个问题?
答案 0 :(得分:1)
目前还不是很清楚如何使用图像 - 也许您应该将代码发布到实际显示图像的位置。
如果两个分辨率的像素长宽比(PAR)不同,图像可能会在不同分辨率下出现变形 - 这是您的情况吗?是否要显示独立于PAR的图像?
在这种情况下,您需要将图像内部保持在已知的DPI值(通常为96),然后使用您的方法将其拉伸为当前分辨率的DPI值,可以通过以下方式获得:
Single xDpi, yDpi;
IntPtr dc = GetDC(IntPtr.Zero);
using(Graphics g = Graphics.FromHdc(dc))
{
xDpi = g.DpiX;
yDpi = g.DpiY;
}
if (ReleaseDC(IntPtr.Zero) != 0)
{
// GetLastError and handle...
}
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern Int32 ReleaseDC(IntPtr hwnd);
然后你需要缩放图像,使最终宽度=原始宽度* 96 / xDpi,高度相似。
答案 1 :(得分:1)
我尝试调用以下方法 OnResize事件,虽然它适用于 第一次迭代,图像得到 随后调整大小和 最后我终于失去了我的形象。
我认为您应该使用DisplaySettingsChanged而不是OnResize事件,只有在更改分辨率时才会触发。