캔버스 배경이 lineargradientbrush로 설정되어 있습니다 .... 어떻게 특정 마우스 포인트 (x, y)에서이 배경 색상을 추출 할 수 있습니까?캔버스 배경색 검색을위한 배경
나는 BitmappedImage이 할 수있는 좋은 ...이 ...하지만 캔버스에 대해 확실하지 픽셀로
크게 미리감사합니다,
U.
캔버스 배경이 lineargradientbrush로 설정되어 있습니다 .... 어떻게 특정 마우스 포인트 (x, y)에서이 배경 색상을 추출 할 수 있습니까?캔버스 배경색 검색을위한 배경
나는 BitmappedImage이 할 수있는 좋은 ...이 ...하지만 캔버스에 대해 확실하지 픽셀로
크게 미리감사합니다,
U.
WPF는 V입니다 : 마이크로 소프트 지원, 마우스 커서의 픽셀의 색을 찾는 것에 대해이 문서가 ector를 기반으로하므로 비트 맵 데이터 구조 내에서를 제외하고는 "픽셀"개념을 실제로 갖고 있지 않습니다. 그러나 1x1 직사각형 영역 (일반적으로 물리적 화면에서 단일 픽셀로 표시됨)을 포함하여 직사각형 영역의 평균 색상을 결정할 수 있습니다. 이 코드가 작동
Color pixelColor = GetPixelColor(canvas, x, y);
방법은 다음과 같습니다 :
public Color GetPixelColor(Visual visual, int x, int y)
{
return GetAverageColor(visual, new Rect(x,y,1,1));
}
public Color GetAverageColor(Visual visual, Rect area)
{
var bitmap = new RenderTargetBitmap(1,1,96,96,PixelFormats.Pbgra32);
bitmap.Render(
new Rectangle
{
Width = 1, Height = 1,
Fill = new VisualBrush { Visual = visual, Viewbox = area }
});
var bytes = new byte[4];
bitmap.CopyPixels(bytes, 1, 0);
return Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3]);
}
당신이 그것을 사용하는 것이 방법입니다
다음은이 작업을 수행하는 방법 캔버스의 선택된 영역을 보여주는 VisualBrush 사용하기
레이 번스에 의해 게시 코드는 나를 위해 작동하지 않았다하지만 올바른 경로를 날 실망 이어질 않은에서 픽셀의 색상을 얻을에 사각형입니다. 몇 가지 연구와 실험을 마친 후 문제점을 bitmap.Render (...) 구현과 사용하는 Viewbox로 지정했습니다.
참고 : .Net 3.5와 WPF를 사용하고 있으므로 다른 버전의 .Net에서 작동 할 수도 있습니다.
코드를 설명하기 위해 의도적으로 의견을 남겼습니다.
원본 크기의 Visual Height와 Width를 기준으로 Viewbox를 표준화해야합니다.
DrawingVisual은 렌더링되기 전에 DrawingContext를 사용하여 그려야합니다.
RenderTargetBitmap 메서드에서 PixelFormats.Default와 PixelFormats.Pbgra32를 모두 시도했습니다. 내 테스트 결과는 두 사람 모두 동일했습니다.
다음은 코드입니다. 당신이 getScreenDPI (에 관심이 있다면
public static Color GetPixelColor(Visual visual, Point pt)
{
Point ptDpi = getScreenDPI(visual);
Size srcSize = VisualTreeHelper.GetDescendantBounds(visual).Size;
//Viewbox uses values between 0 & 1 so normalize the Rect with respect to the visual's Height & Width
Rect percentSrcRec = new Rect(pt.X/srcSize.Width, pt.Y/srcSize.Height,
1/srcSize.Width, 1/srcSize.Height);
//var bmpOut = new RenderTargetBitmap(1, 1, 96d, 96d, PixelFormats.Pbgra32); //assumes 96 dpi
var bmpOut = new RenderTargetBitmap((int)(ptDpi.X/96d),
(int)(ptDpi.Y/96d),
ptDpi.X, ptDpi.Y, PixelFormats.Default); //generalized for monitors with different dpi
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
dc.DrawRectangle(new VisualBrush { Visual = visual, Viewbox = percentSrcRec },
null, //no Pen
new Rect(0, 0, 1d, 1d));
}
bmpOut.Render(dv);
var bytes = new byte[4];
int iStride = 4; // = 4 * bmpOut.Width (for 32 bit graphics with 4 bytes per pixel -- 4 * 8 bits per byte = 32)
bmpOut.CopyPixels(bytes, iStride, 0);
return Color.FromArgb(bytes[0], bytes[1], bytes[2], bytes[3]);
}
)는 코드가 작동 :
public static Point getScreenDPI(Visual v)
{
//System.Windows.SystemParameters
PresentationSource source = PresentationSource.FromVisual(v);
Point ptDpi;
if (source != null)
{
ptDpi = new Point(96.0 * source.CompositionTarget.TransformToDevice.M11,
96.0 * source.CompositionTarget.TransformToDevice.M22 );
}
else
ptDpi = new Point(96d, 96d); //default value.
return ptDpi;
}
그리고 사용은 레이의 유사합니다. 캔버스에있는 MouseDown에 대해 여기에 표시합니다.
private void cvsTest_MouseDown(object sender, MouseButtonEventArgs e)
{
Point ptClicked = e.GetPosition(cvsTest);
if (e.LeftButton.Equals(MouseButtonState.Pressed))
{
Color pxlColor = ImagingTools.GetPixelColor(cvsTest, ptClicked);
MessageBox.Show("Color String = " + pxlColor.ToString());
}
}
FYI, ImagingTools는 이미징과 관련된 정적 메소드를 유지하는 클래스입니다.
코드를 사용해 보았지만 System.ArgumentOutOfRangeException이 발생했습니다. Sth like : "매개 변수 값은 bitmap.CopyPixels (바이트, 1, 0)에서 4보다 작을 수 없습니다." 내 매개 변수는 x = 57, y = 78입니다. bitmap.CopyPixels (bytes, 4, 0)을 사용하면 "바이트"는 항상 "0"을 유지하므로 투명 검정색을 나타냅니다. – Torsten