2012-11-30 5 views
3

두 개의 서로 다른 확대 이미지가 화면에 사용자 지정됩니다. 그들 각각은 화면의 절반을 차지합니다.이미지의 사용자 지정 그리기 부분 .net 012

는 내가 이전의 OnPaint() 오버라이드 (override) (내 생각) 3.5 .NET에서 일을 한

:

//using System.Drawing 

    /// <summary> 
    /// Custom drawing 
    /// </summary> 
    /// <param name="e"></param> 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     e.Graphics.DrawImage(Image, DestRectangle, SrcRectangle, GraphicsUnit); 
    } 

의 drawImage 메소드의 설명 : "지정된에 지정된 이미지의 특정 부분을 그립니다 위치 및 지정된 크기. " (MSDN)

.net 4.5를 사용하여 동일한 작업을 수행하려고합니다. OnRender를 재정의하고 DrawingContext 객체를 사용하여 드로잉을 수행합니다. 기본적으로 이것은 내 루프입니다.

//using System.Windows.Media; 

    /// <summary> 
    /// Overide the OnRender to have access to a lower level of drawing. 
    /// </summary> 
    /// <param name="drawingContext"></param> 
    protected override void OnRender(DrawingContext drawingContext) 
    { 
     drawingContext.DrawImage(BitmapImage_Left, Window_LeftHalf); 
     drawingContext.DrawImage(BitmapImage_Right, Window_RightHalf); 
    } 

확장 된 그림을 표시하려면 잘 작동합니다. 내가 원하는 것은 (Window_LeftHalf와 Window_RightHalf에서) 그림의 일부분을 (확대와 같이) 표시하는 것입니다. 기본적으로 어떤 graphics.DrawImage (위를보십시오)하지만 DrawingContext 객체를 사용합니다.

MSDN을 살펴 보았지만 흥미로운 것을 끌어낼 수 없었습니다. DrawingContext에 의해 나중에 사용되는 버퍼를 만드는 것일까 요? 축소 된 이미지를 보유하는 중간 객체가 필요하다는 것은 거의 확실합니다. 어떤 아이디어?

업데이트 : 이미지를 탐색 할 때 마우스를 사용하고 있으므로 성능이 인 경우이 중요합니다.

/// <summary> 
    /// Handles the mouse move events. 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private static void MouseMoveEventHandler(RoutedEventArgs e) 
    { 
     // The size of the crop is always the same 
     // but the portion of the picture different. 
     crop.X += mouseDelta.X; 
     crop.Y += mouseDelta.Y; 
    } 

답변

3

CroppedBitmap 클래스를 살펴보십시오. . 당신이 e.Graphics.DrawImage()과 함께 할 수 있기를 사용하는 것처럼, CroppedBitmap 다음은 관심있는 이미지의 단지 부분을 지정

을 허용하는 예이다 : 답장을

protected override void OnRender(System.Windows.Media.DrawingContext dc) 
{ 
    int halfWidth = (int)this.Width/2; 
    int height = (int)this.Height; 
    BitmapImage leftImage = new BitmapImage(new Uri(@"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg")); 
    BitmapImage rightImage = new BitmapImage(new Uri(@"C:\Users\Public\Pictures\Sample Pictures\Desert.jpg")); 
    CroppedBitmap leftImageCropped = new CroppedBitmap(leftImage, new Int32Rect(0, 0, halfWidth, height)); 
    CroppedBitmap rightImageCropped = new CroppedBitmap(rightImage, new Int32Rect(0, 0, halfWidth, height)); 
    dc.DrawImage(leftImageCropped, new System.Windows.Rect(0, 0, leftImageCropped.Width, height)); 
    dc.DrawImage(rightImageCropped, new System.Windows.Rect(halfWidth, 0, halfWidth, height)); 
} 
+0

안녕하세요, cokeman19, 답장을 보내 주셔서 감사합니다. 예! 나는 그것을 아직 시도하지 않았지만, 내가 원하는 것처럼 보입니다. 유일한 차이점은 이미지의 새 섹션이 필요할 때마다 'e.Graphics.DrawImage()'가 항상 동일한 비트 맵을 사용하는 CroppedBitmap 객체를 만들고 수정해야한다는 것입니다. 어쨌든 고마워, 내가 사용할거야. 내 게시물을보다 구체적인 문제로 업데이트하겠습니다. – jimasun

0

편집 2 : ImageBrush.Viewbox 예를 들어. Viewbox는 크기가 [0.0 ... 1.0] 인 Rect으로, 이전에는 SourceRect였던 것을 제어 할 수있었습니다. 나는 이것을 테스트했고 훌륭하게 작동합니다. 내가 무슨 짓을 :

을 내 창에서 : 이것에 대한

protected ImageBrush imgBrush = new ImageBrush(new ImageSource(new Uri("image.png"))); 
    protected Rect vBox = new Rect(0, 0, 1, 1); 
    protected Point lastPosition = new Point(0, 0); 

내 컨테이너는 WPF 사각형 누구의 Rect.FillimgBrush했다 tgtRect라고했다. 구현을 위해

protected void tgtRect_MouseWheel(object sender, MouseWheelEventArgs e) 
    { 
     // Zoom in when Delta is positive, Zoom out when negative 
     double exp = -e.Delta/Math.Abs(e.Delta); 
     double val = Math.Pow(1.1, exp); 
     vBox.Scale(val, val); 
     imgBrush.Viewbox = vBox; 
    } 

    void tgtRect_MouseMove(object sender, MouseEventArgs e) 
    { 
     Point thisPosition = e.GetPosition(tgtRect); 
     if (e.RightButton == MouseButtonState.Pressed) 
     { 
      double w = tgtRect.ActualWidth; 
      double h = tgtRect.ActualHeight; 
      Vector offset = lastPosition - thisPosition; 
      offset.X /= w; 
      offset.Y /= h; 
      vBox.Offset(offset); 
      imgBrush.Viewbox = vBox; 
     } 
     lastPosition = thisPosition; 
    } 

:

protected override void OnRender(DrawingContext drawingContext) 
    { 
     drawingContext.DrawRectangle(imgBrush, null, DesRect); 
    } 

당신은 아마 당신이 그리는하려는 각 사각형에 대해 별도의 imgBrush을 유지해야합니다 다음과 같이 줌과 스크롤 방법이었다. WPF 창에서 위의 코드 (OnRender 오버라이드가 아닌)를 시도했는데 그 중 Rectangle.FillImageBrush이고 성능이 매우 좋았습니다. 문제가 발생하면 문제를 해결할 수 있다고 생각하지만 ImageBrush가 올바른 구현으로 끝날 것입니다. 이것은 매우 흥미로운 프로젝트입니다! 질문 해 주셔서 감사합니다.

최종 편집 당신은 "Window_LeftHalf"와 "Window_RightHalf는"당신이 이미지를 렌더링 할 실제 크기가되도록 Rect 객체를 정의해야합니다 2

.예를 들어 200 % 확대 한 경우 Rect.WidthRect.Height 속성은 원래 ImageSource 크기의 2 배가되어야합니다.

편집 :

오래된 방법이었다

protected override void OnPaint(PaintEventArgs e) 
{ 
    e.Graphics.DrawImage(Image, DestRectangle, SrcRectangle, GraphicsUnit); 
} 

'BitmapImage.SourceRect` 사용 :

protected override void OnRender(DrawingContext drawingContext) 
{ 
    BitmapImage_Left.SourceRect = SrcRectangleLeft; 
    drawingContext.DrawImage(BitmapImage_Left, Window_LeftHalf); 
    BitmapImage_Right.SourceRect = SrcRectangleRight; 
    drawingContext.DrawImage(BitmapImage_Right, Window_RightHalf); 
} 

마우스 기능은으로서, sourceRect을 변경할 수 있습니다. 예를 들면 다음과 같습니다.

private static void MouseMoveEventHandler(RoutedEventArgs e) 
{ 
    // The size of the crop is always the same 
    // but the portion of the picture different. 
    SrcRectangleLeft = new Int32Rect(SrcRectangleLeft.X + mouseDelta.X, 
     SrcRectangleLeft.Y + mouseDelta.Y, 
     SrcRectangleLeft.Width, SrcRectangleLeft.Height); 
} 

성능은 어떻게 될지 모르지만 비트 맵의 ​​일부를 각 업데이트에 새 개체에 매핑하는 것보다 낫습니다.

희망이있어 도움이되었습니다.

+0

newb 안녕하세요, 감사합니다. 나는 전에 그것을 시도했다. 그렇게하면 이미지가 겹칠 것입니다. 올바른 위치에 표시하더라도 Window_ * Half는 이미지의 특정 * 부분을 표시하지 않습니다 (확대/축소). – jimasun

+0

대상 사각형의 위치를 ​​변경하지 않으면 의미가 있습니다. 나는 이것을 다시 읽고 윈도우의 각 절반에 대해 나란히 스크롤하는 창을 상상하고있다. 그게 맞습니까? – newb

+0

예, 고정 된 "창"을 나란히 배치하십시오. 그러나 내용은 항상 변하고 있습니다. 따라서 200 %를 표시하면 고정 된 내용 (x 축) 만 가질 수 있습니다. – jimasun

관련 문제