2012-01-23 3 views
1

내가 이미지의 색상을 변경하고 크기를 조정하려고하면, 그것은 단지 원본 이미지 크기를 조정합니다. 왜 이런 일이 일어나고 어떻게 해결할 수 있습니까? 나는 또한 사용자가 버튼을 클릭하고 올바른 메소드를 호출하도록 적절한 값으로 bools을 설정할 때 처리 방법을변경된 이미지의 크기를 조정할 수 없습니까? C#을 윈폼

private PrintDocument printDoc = new PrintDocument(); 
private PageSettings pgSettings = new PageSettings(); 
private PrinterSettings prtSettings = new PrinterSettings(); 

Bitmap myBitmapImage;  // image (bitmap) for some background mountains 
Boolean isInvert = false; 
Boolean isLOaded = false; 
Boolean isGrayscale = false; 
Boolean isThreshold = false; 
Boolean isResize = false; 

OpenFileDialog ofd; 
Bitmap bmBack; 

public EditImage() 
{ 
    printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage); 

    InitializeComponent(); 
    this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true); 
} 

private void EditImage_Load(object sender, EventArgs e) 
{ 

} 

private void EditImage_Paint(object sender, PaintEventArgs e) 
{ 
    if (isLOaded == true) 
    { 
     Graphics gWindow; // reference to the graphic surface of this window 
     Graphics gBack;  // reference to in-memory surface 

     bmBack = new Bitmap(Width, Height);  // bitmap for window surface copy 

     gWindow = e.Graphics; // get our current window's surface 
     gBack = Graphics.FromImage(bmBack);  // create surfaces from the bitmaps 

     gBack.DrawImage(myBitmapImage, 0, 0, Width, Height); 

     if (isInvert == true) 
     { 
      InvertBitmap(bmBack); 
     } 
     else if (isGrayscale == true) 
     { 
      GrayscaleBitmap(bmBack); 
     } 
     else if (isThreshold == true) 
     { 
      ThresholdBitmap(bmBack); 
     } 
     else if (isResize == true) 
     { 
      bmBack = resizeImage(bmBack, 10, 100); 
     } 

     gWindow.DrawImage(bmBack, 0, 0); 
    } 
} 
private void toolStripMenuItemLoadImage_Click(object sender, EventArgs e) 
{ 
    using (ofd = new OpenFileDialog()) 
    { 
     ofd.Title = "Load Image"; 

     if (ofd.ShowDialog() == DialogResult.OK) 
     { 
      myBitmapImage = new Bitmap(ofd.FileName); 
      this.Invalidate(); 
     } 
    } 
    isLOaded = true; 
} 


private void GrayscaleBitmap(Bitmap bmp) 
{ 
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
    System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, 
     System.Drawing.Imaging.PixelFormat.Format32bppRgb); 

    IntPtr ptr = bmpData.Scan0; 

    int numPixels = bmpData.Width * bmp.Height; 
    int numBytes = numPixels * 4; 
    byte[] rgbValues = new byte[numBytes]; 

    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes); 

    for (int i = 0; i < rgbValues.Length; i += 4) 
    { 
     byte gray = (byte)(.3 * rgbValues[i + 0]); //blue 
     gray += (byte)(.59 * rgbValues[i + 1]); //green 
     gray += (byte)(.11 * rgbValues[i + 2]); //red 

     rgbValues[i + 0] = gray; //blue 
     rgbValues[i + 1] = gray; //green 
     rgbValues[i + 2] = gray; //red 
    } 

    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, numBytes); 

    bmp.UnlockBits(bmpData); 
} 

private Bitmap resizeImage(Bitmap sourceBMP, int width, int height) 
{ 
    Bitmap result = new Bitmap(width, height); 
    using(Graphics g = Graphics.FromImage(result)) 
    g.DrawImage(sourceBMP, 0, 0, width, height); 

    return result; 
} 

:

여기 내 코드입니다. 잘못된 여기에 일이 많이 있습니다 ...

답변

4

을하지 원본 이미지 - 의도 한대로 ..하지만 난 크기 조정을 클릭하면, 나는 색상을 변경 한 이미지의 버전을 크기를 조정할 - 이미지는 색상을 변경합니까 :

resizeImage()

    당신은 그래픽을 처리해야
  • 당신이 여기 만들
  • 여기에서 무효로 호출하지 마십시오 (A 사용() 문에 래핑)이 객체 ,이 기능 이미지의 크기를 조정하면 이미지를 변경 한 후에 무효화됩니다. image와 Paint 메서드는 현재 변경된 이미지를 페인트합니다.
  • 당신은 또한 함수를 반환 직전에 당신이 더 이상에 대한 사용이없는 경우 sourceBMP의 처분에 대해 생각해야한다.

GrayscaleBitmap는()

  • 이 바로 보이지만, 여기에 다시 무효화 할 이유가 없습니다. 호출하는 함수에서이 메서드를 호출 한 후에는 무효화해야합니다. 그것은 더 의미가 있습니다.

당신은 당신의 Paint 이벤트 내에서이 함수를 호출하지 않아야

  • EditImage_Paint. 그리고 각 그림판에 새로운 비트 맵과 새로운 그래픽 클래스를 만들어서는 안됩니다. 이것은 필요한 것보다 더 많은 일입니다. 이 함수는 사용자 입력에 따라 데이터를 변경해야 할 때만 실행해야합니다 (사용자가 회색 음영 효과를 적용하려면 버튼을 클릭 함).

원하는대로 최대 2 개의 비트 맵 변수 만 있으면됩니다. 하나는 당신이 사용자가이를 "재설정"또는 효과를 취소 할 수 있도록 할 경우에 수정되지 않은 원래 비트 맵 저장 (대부분의 효과는 영구적 인 데이터 손실이 발생할를 다시 그레이 스케일 이미지의 색상을 만들 수 없습니다). 그리고 다른 하나는 그려진 비트 맵을 저장합니다. 사용자가 효과를 적용 할 때마다 두 번째 비트 맵을 수정 한 다음 무효화를 호출합니다.

모든 2 비트 맵을 그릴되어 어떻게해야 당신의 페인트 기능 :

Bitmap originalBitmap; // load from file, do not modify 
Bitmap currentBitmap; // when user clicks an effect, modify this bitmap and then Invalidate afterward 

private void EditImage_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 

    // Draw the currentBitmap centered on the window 
    SizeF clientSize = this.ClientSize; 

    double zoomRatio = Math.Min(
     clientSize.Width/currentBitmap.Width, 
     clientSize.Height/currentBitmap.Height 
    ); 

    SizeF zoomedSize = new SizeF(
     (float)(currentBitmap.Width * zoomRatio), 
     (float)(currentBitmap.Height * zoomRatio) 
    ); 

    PointF imageOffset = new PointF(
     (clientSize.Width - zoomedSize.Width)/2, 
     (clientSize.Height - zoomedSize.Height)/2 
    ); 

    e.Graphics.Clear(Color.White); 
    e.Graphics.DrawImage(currentBitmap, imageOffset.X, imageOffset.Y, zoomedSize.Width, zoomedSize.Height); 
} 

이 컨트롤에 이미지를 센터와 창에 맞게 그것을 그리는 간단한 줌 효과를 에뮬레이트합니다.

+0

감사합니다, 그래서 난 당신이 내 페인트 방법을 해결하는 방법을 이해하지 제외 ... 제안 모든 변경 사항을했습니다 ... 당신은 내게 내가 그렇게 할 것입니다 방법의 예를 줄 수 있습니까? 당신이 할 수있는 일의 예와 업데이트 도움 – BigBug

+0

+1. – BigBug

+0

에 대한 –

관련 문제