2012-06-14 5 views
3

그레이 스케일로 모든 폼을 그리는 것이 가능합니까 (Paint 메서드를 재정의하지 않고).그레이 스케일로 폼 표시

모달() 대화 상자에 양식을 표시하면 부모를 그레이 스케일로 표시하지 않을 것입니다. Visual Studio Extension Manager에서이 사실을 발견했습니다. 진행률 표시 줄에서 패키지를 다운로드하는 경우 기본 창이 흐리게 표시됩니다.

나는이 생각하고 :

private void Button1_Click(object sender, EventArgs e) 
{ 
    using (var dialog = new Form2()) 
    { 
     SetGrayscale(this, true); 
     dialog.ShowDialog(); 
     SetGrayscale(this, false); 
    } 
} 

업데이트 그냥 Form.Enabled = false; 설정

내가 의도하지 않습니다. 그건 내 양식의 그레이 스케일 표현만큼 좋지 않아. 나는 리눅스 용 compiz 윈도우 데코레이터가 응답이없는 앱으로 이것을했다고 생각한다.

+1

나는 회색 형태가 폼에 추가 컨트롤을 추가하는 것입니다 수 있도록하는 데 사용하는 신속하고 더러운 트릭. 그 컨트롤은 그것의 부모 ('Form.DrawToBitmap()')의 사진을 찍을 것이고, 그것을 조작하고, 그것을 배경으로 사용하고, 완전한 형태를 채우기 위해 최대화 할 것입니다. – Bobby

+0

회색 음영이 아닌 회색 음영 – Indy9000

+0

@Indeera 어느 쪽이든 맞습니다. http://en.wikipedia.org/wiki/Grayscale – Keplah

답변

1

이미 언급했듯이 기존 양식 위에 다른 컨트롤/양식을 겹쳐서 그 위에 회색 음영 버전을 렌더링하는 것이므로 추가 양식을 정확하게 배치하여이 작업을 수행 할 수 있습니다 원래 양식을 사용하거나 Panel과 같은 것을 사용하여 다른 모든 컨트롤 위에 배치 할 수 있습니다.

다음은 첫 번째 양식의 클라이언트 영역 위에 다른 양식을 정확하게 배치 할 때 수행 할 수있는 작업 예제입니다. 된다는 사실을

using (Grayscale(this)) 
{ 
    MessageBox.Show("Test"); 
} 

구현

public static Form Grayscale(Form tocover) 
{ 
    var frm = new Form 
     { 
      FormBorderStyle = FormBorderStyle.None, 
      ControlBox = false, 
      ShowInTaskbar = false, 
      StartPosition = FormStartPosition.Manual, 
      AutoScaleMode = AutoScaleMode.None, 
      Location = tocover.PointToScreen(tocover.ClientRectangle.Location), 
      Size = tocover.ClientSize 
     }; 
    frm.Paint += (sender, args) => 
     { 
      var bmp = GetFormImageWithoutBorders(tocover); 
      bmp = ConvertToGrayscale(bmp); 
      args.Graphics.DrawImage(bmp, args.ClipRectangle.Location); 
     }; 

    frm.Show(tocover); 
    return frm; 
} 

private static Bitmap ConvertToGrayscale(Bitmap source) 
{ 
    var bm = new Bitmap(source.Width, source.Height); 
    for (int y = 0; y < bm.Height; y++) 
    { 
     for (int x = 0; x < bm.Width; x++) 
     { 
      Color c = source.GetPixel(x, y); 
      var luma = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11); 
      bm.SetPixel(x, y, Color.FromArgb(luma, luma, luma)); 
     } 
    } 
    return bm; 
} 

private static Bitmap GetControlImage(Control ctl) 
{ 
    var bm = new Bitmap(ctl.Width, ctl.Height); 
    ctl.DrawToBitmap(bm, new Rectangle(0, 0, ctl.Width, ctl.Height)); 
    return bm; 
} 

private static Bitmap GetFormImageWithoutBorders(Form frm) 
{ 
    // Get the form's whole image. 
    using (Bitmap wholeForm = GetControlImage(frm)) 
    { 
     // See how far the form's upper left corner is 
     // from the upper left corner of its client area. 
     Point origin = frm.PointToScreen(new Point(0, 0)); 
     int dx = origin.X - frm.Left; 
     int dy = origin.Y - frm.Top; 

     // Copy the client area into a new Bitmap. 
     int wid = frm.ClientSize.Width; 
     int hgt = frm.ClientSize.Height; 
     var bm = new Bitmap(wid, hgt); 
     using (Graphics gr = Graphics.FromImage(bm)) 
     { 
      gr.DrawImage(wholeForm, 0, 0, 
       new Rectangle(dx, dy, wid, hgt), 
       GraphicsUnit.Pixel); 
     } 
     return bm; 
    } 
} 

참고 사용 방법 :

  • Paint의 구현은 매우 가난을 - 그레이 스케일 이미지가 사전되도록 정말 이중 버퍼링을 사용해야합니다 버퍼링 된 그래픽 컨텍스트에 렌더링되므로, Paint 메서드는 미리 그려진 버퍼 내용을 그릴 필요가 있습니다. Custom Drawing Controls in C# – Manual Double Buffering
  • ConvertToGrayscale가 느린 측에 조금이지만, 아마도 누군가가
  • 이미지가 정적 어떤 이유로 원래의 형태를 이동 관리하는 경우, 잘못 기본 제어하면됩니다
  • 상황을 가속화 할 수 있습니다 참조 다시 그리면 맨 위 양식도 다시 그려야합니다. 다른 양식의 일부가 무효화되었을 때이를 어떻게 감지하는지 잘 모르겠습니다.

시간을 찾으면 그 중 일부 문제를 해결할 것입니다.하지만 위의 사항은 일반적인 아이디어를 제공합니다.

WPF에서는이 작업이 훨씬 쉽습니다.

출처 :

+0

약간의 개선이 필요하지만 처음에는 잘 보입니다. –

0

대부분의 간단한 컨트롤 (모든 컨트롤을 올바르게 전환하려면 컨테이너로 다시 보내야 함)에서 작동하는 이와 같은 것을 시도해보십시오.

private void button1_Click(object sender, EventArgs e) 
    { 
     using (var dialog = new Form()) 
     { 
      Dictionary<Control, Tuple<Color, Color>> oldcolors = new Dictionary<Control, Tuple<Color, Color>>(); 
      foreach (Control ctl in this.Controls) 
      { 
       oldcolors.Add(ctl, Tuple.Create(ctl.BackColor, ctl.ForeColor)); 
       // get rough avg intensity of color 
       int bg = (ctl.BackColor.R + ctl.BackColor.G + ctl.BackColor.B)/3; 
       int fg = (ctl.ForeColor.R + ctl.ForeColor.G + ctl.ForeColor.B)/3; 
       ctl.BackColor = Color.FromArgb(bg, bg, bg); 
       ctl.ForeColor = Color.FromArgb(fg, fg, fg); 
      } 

      dialog.ShowDialog(); 

      foreach (Control ctl in this.Controls) 
      { 
       ctl.BackColor = oldcolors[ctl].Item1; 
       ctl.ForeColor = oldcolors[ctl].Item2; 
      } 
     } 
    } 
1

직접 할 방법이 없다고 생각합니다. 모든 양식이 sRGB로 렌더링되어 있다고 생각합니다. 해커는 이미지의 복사본을 이미지로 오버레이하여 (Control.DrawToBitMap과 같이 간단 함) 간단한 GDI 행렬을 통해 http://www.bobpowell.net/grayscale.htm을 채도화할 수 있습니다.

관련 문제