2014-04-15 2 views
0

이 코드를 사용하여 winform에 스크롤 가능한 패널을 그립니다. ImageBox는 512 × 512이고, 내가 사용하고 이미지 (리소스로 추가) 1024 × 768이다 :패널에 스케일 된 이미지가 표시됩니다.

imageBox1.Image = Properties.Resources.test; 

불행하게도, 그것은 이미지가 어떤 이유로 축소되어 보인다 - 그것은 국경의에 나는 스크롤 할 수 없습니다. 512x512 이미지를 사용하면 이미지 상자에 맞지 않아 잘린 것처럼 보입니다. 여기서 무슨 일이 벌어지고 있는거야?

using System; 
using System.Drawing; 
using System.Windows.Forms; 

class ImageBox : Panel { 
    public ImageBox() { 
     this.AutoScroll = true; 
     this.DoubleBuffered = true; 
    } 
    private Image mImage; 
    public Image Image { 
     get { return mImage; } 
     set { 
      mImage = value; 
      if (mImage != null) this.AutoScrollMinSize = mImage.Size; 
      else this.AutoScrollMinSize = new Size(0, 0); 
      this.Invalidate(); 
     } 
    } 
    protected override void OnPaint(PaintEventArgs e) { 
     e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y); 
     if (mImage != null) e.Graphics.DrawImage(mImage, 0, 0); 
     base.OnPaint(e); 
    } 
} 
+0

제목을 편집했습니다. "[제목에"태그 "가 포함되어 있어야합니까?] (http://meta.stackexchange.com/questions/19190/)"합의가 "아니오, 그렇지 않아야합니다"로 표시되어야합니다. –

+0

winform에서 패널의 크기는 얼마입니까? 도크로 가득 차 있나? –

답변

2

이미지의 해상도에 문제가 있으며 디스플레이의 해상도보다 낮습니다. 꽤 특이한.

하나 이상의 해결 방법이 있습니다. @ TaW의 접근 방식은 작동하지만 모니터 해상도를 선호합니다. 더 선명한 이미지를 얻을 수는 있지만 원래 기록 된 이미지 크기에 가까워지지는 않습니다. 다른 방법은 DrawImage()가하는 것처럼 실제 크기를 유지하고 이에 따라 스크롤 막대를 조정하는 것입니다. 아마 당신은 필요에 따라 변경할 수 있도록 다른 속성을 추가하는 것을 고려한다고, "올바른"방식이 그렇게 명확하지 않다 따기

set { 
     mImage = value; 
     if (value == null) this.AutoScrollMinSize = new Size(0, 0); 
     else { 
      var size = value.Size; 
      using (var gr = this.CreateGraphics()) { 
       size.Width = (int)(size.Width * gr.DpiX/value.HorizontalResolution); 
       size.Height = (int)(size.Height * gr.DpiY/value.VerticalResolution); 
      } 
      this.AutoScrollMinSize = size; 
     } 
     this.Invalidate(); 
    } 

:에 이미지 속성 setter을 변경합니다.

+0

당신은 전문가입니다.하지만 궁금합니다. 왜 이미지가 자체 크기로 그려지면 이미지가 왜곡됩니까? (2 차 픽셀이라고 가정합니다.) – TaW

+0

죄송합니다, 당신 말이 맞습니다. 나는 reworded. –

2

DrawImage에는 많은 변형이 있으므로주의 깊게 확인해 볼 가치가 있습니다. 당신은 당신의 목적에 맞는 것을 잘못 선택했습니다. MSDN에서 문서 봐 : 언뜻

Graphics.DrawImage Method (Image, Int32, Int32) 
... 
Draws the specified image, using its original physical size, 
at the location specified by a coordinate pair. 

이 좋은 소리. '물리적 크기'- 픽셀이 아닌가요? 그러나 MSDN에서 읽어 :

Remarks 

An Image stores a value for pixel width and a value for horizontal resolution 
(dots per inch). The physical width, measured in inches, of an image is 
the pixel width divided by the horizontal resolution. For example, 
an image with a pixel width of 216 and a horizontal resolution of 72 dots 
per inch has a physical width of 3 inches. Similar remarks apply to pixel 
height and physical height. 

The DrawImage method draws an image using its physical size, so the image will 
have its correct size in inches regardless of the resolution (dots per inch) 
of the display device. For example, suppose an image has a pixel width of 216 
and a horizontal resolution of 72 dots per inch. If you call DrawImage to 
draw that image on a device that has a resolution of 96 dots per inch, 
the pixel width of the rendered image will be (216/72)*96 = 288. 

아야를, 그 후에 모든 픽셀에 대해 아니에요! 그것은 디스플레이와 이미지에 포함 된 해상도에 관한 것입니다. 이미지를 가져 오려면이 기능이 유용합니다. 모든 프린터에이 인쇄되어 있습니다.

하지만 이미지의 픽셀을 디스플레이의 픽셀과 일치 시키길 원합니다. 당신 수 있습니다 귀하의 화면에 이미지의 해상도를 적응; 하지만 다른 화면에서는 작동하지 않습니다. 그래서이의 drawImage 호출이 .. 당신을 위해 작동하지 않습니다

그래서 당신은 아주 간단하게 오른쪽의 drawImage 통화로 이미지가 픽셀 수를 사용하고 공급한다 : 이제

e.Graphics.DrawImage(mImage, 0, 0, mImage.Width, mImage.Height); 

그것을하지 않습니다 이미지를 왜곡하지만 하나의 이미지 픽셀을 하나의 화면 픽셀에 배치하십시오 ..

편집 : 참고 : 저는 OP에서 MSDN을 잘못 인용했습니다. 이제 오른쪽 (그러나 목적에 맞지 않음) 메서드 호출은 첫 번째 부분에서 인용됩니다.

관련 문제