2016-10-06 3 views
0

私は自分自身のスニッピングツールをプログラムしようとしました。選択した領域のサイズがピクセルのサイズと一致しないことを除いて、これはかなりうまく動作します。スクリーンショットを撮る - サイズが一致しない

私は不透明度の低いウィンドウを作成し、長方形を描いてサイズと位置を取得します。ウィンドウのサイズは300x300です(後でフルスクリーンにする必要があります)。ただし、スナップツールでスクリーンショットを撮ると、サイズは375x375ピクセルになります。だから私が自分のプログラマーでscrennshotを撮るとき、私は実際に欲しかったすべての機能を捕まえていません。

最後の目標は、同じ位置の複数のスクリーンショットをショートカット(実装されていない)で取得し、特定の領域でOCR(実装されていない)を行い、OCR結果に対応するファイル名を作成することです。ここで

はコードです:

メインウィンドウのC#:

int number = 0; 

    System.Windows.Point scsh_Start; 
    System.Windows.Point scsh_Ende; 
    System.Windows.Point OCR_Start; 
    System.Windows.Point OCR_Ende; 

    public MainWindow() 
    { 
     InitializeComponent();    
    } 


    private void button_Click(object sender, RoutedEventArgs e) 
    { 
     int Width = (int)(Math.Abs(scsh_Start.X - scsh_Ende.X)); 
     int Height = (int)(Math.Abs(scsh_Start.Y - scsh_Ende.Y)); 
     using (Bitmap bmpScreenCapture = new Bitmap(Width, 
             Height)) 
     { 
      using (Graphics g = Graphics.FromImage(bmpScreenCapture)) 
      {      
       string outputNumber = ""; 
       if (number < 10) 
       { 
        outputNumber = "00" + number.ToString(); 
       } 
       else if (number < 100) 
       { 
        outputNumber = "0" + number.ToString(); 
       } 
       else 
       { 
        outputNumber = number.ToString(); 
       } 
       Opacity = .0;      
       g.CopyFromScreen((int)scsh_Start.X, 
           (int)scsh_Start.Y, 
           0, 0, 
           bmpScreenCapture.Size); 
       Directory.CreateDirectory("C:\\Users\\Public\\Pictures\\Sample Pictures\\ScreenSave"); 
       bmpScreenCapture.Save("C:\\Users\\Public\\Pictures\\Sample Pictures\\ScreenSave\\test" + outputNumber + ".png"); 
       Opacity = 1; 
       number++; 
      } 
     } 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     this.WindowState = WindowState.Minimized; 
     Window1 w1 = new Window1(); 
     w1.RaiseCustomEvent += pointsScreenshot; 
     w1.ShowDialog(); 

    } 

    private void pointsScreenshot(object sender, customEventArgs e) 
    { 
     if (e.Points[0] == null) 
      return; 
     scsh_Start = e.Points[0]; 
     scsh_Ende = e.Points[1]; 
     B_Image.IsEnabled = true;  
    } 

メインウィンドウのXAML:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:WpfApplication1" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <Button x:Name="B_Image" Content="Image" HorizontalAlignment="Left" Margin="70,31,0,0" VerticalAlignment="Top" Width="75" Click="button_Click" IsEnabled="False"/> 
    <Button x:Name="B_MouseEvents" Content="Mouse" HorizontalAlignment="Left" Margin="70,76,0,0" VerticalAlignment="Top" Width="75" Click="button1_Click"/> 
</Grid> 

セカンダリウィンドウは、矩形のC#を取得します

public partial class Window1 : Window 
{ 
    public event EventHandler<customEventArgs> RaiseCustomEvent; 
    private Point p_Start = new Point(); 
    private Point p_End = new Point(); 
    private Rectangle saveRect = null; 
    private MoveType move = MoveType.Draw; 
    bool top = false; 
    bool left = false; 


    public Window1() 
    { 
     InitializeComponent(); 
     this.Topmost = true; 
     this.Activate(); 
     ////this.WindowState = WindowState.Maximized;  

    } 

    private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     p_Start = e.GetPosition(null); 

     double xAct = e.GetPosition(null).X; 
     double yAct = e.GetPosition(null).Y; 

     if (saveRect != null) 
     { 
      double rectLeft = saveRect.Margin.Left; 
      double rectTop = saveRect.Margin.Top; 
      double rectRight = saveRect.Margin.Left + saveRect.Width; 
      double rectBottom = saveRect.Margin.Top + saveRect.Height; 

      if (between(xAct, rectLeft + 3, rectRight - 3) && 
       between(yAct, rectTop + 3, rectBottom - 3)) 
       move = MoveType.Drag; 

      else if ((between(xAct, rectLeft - 3, rectLeft) || between(xAct, rectRight - 3, rectRight)) && 
       between(yAct, rectTop, rectBottom)) 
      { 
       move = MoveType.ResizeWidth; 
       left = between(xAct, rectLeft - 3, rectLeft + 3); 
      } 
      else if ((between(yAct, rectTop - 3, rectTop) || between(yAct, rectBottom - 3, rectBottom)) && 
       between(xAct, rectLeft, rectRight)) 
      { 
       move = MoveType.ResizeHeight; 
       top = between(yAct, rectTop - 3, rectTop + 3); 
      } 
      else 
       move = MoveType.Draw; 
     } 
     else 
      move = MoveType.Draw; 
    } 

    private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     move = MoveType.Draw; 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 


    } 

    private void Window_MouseMove(object sender, MouseEventArgs e) 
    { 
     double xAct = e.GetPosition(null).X; 
     double yAct = e.GetPosition(null).Y; 

     #region select Cursor 
     if (e.LeftButton != MouseButtonState.Pressed) 
     { 
      if (saveRect != null) 
      { 
       double rectLeft = saveRect.Margin.Left; 
       double rectTop = saveRect.Margin.Top; 
       double rectRight = saveRect.Margin.Left + saveRect.Width; 
       double rectBottom = saveRect.Margin.Top + saveRect.Height; 

       if (between(xAct, rectLeft + 3, rectRight - 3) && 
        between(yAct, rectTop + 3, rectBottom - 3)) 
        Cursor = Cursors.Hand; 

       else if ((between(xAct, rectLeft - 3, rectLeft) || between(xAct, rectRight - 3, rectRight)) && 
        between(yAct, rectTop, rectBottom)) 
        Cursor = Cursors.SizeWE; 
       else if ((between(yAct, rectTop - 3, rectTop) || between(yAct, rectBottom - 3, rectBottom)) && 
        between(xAct, rectLeft, rectRight)) 
        Cursor = Cursors.SizeNS; 

       else Cursor = Cursors.Pen; 
      } 
      else 
       Cursor = Cursors.Pen; 
      return; 
     } 
     else 
     { 
      switch (move) 
      { 
       case MoveType.Drag: 
        Cursor = Cursors.Hand; 
        break; 
       case MoveType.Draw: 
        Cursor = Cursors.Pen; 
        break; 
       case MoveType.ResizeHeight: 
        Cursor = Cursors.SizeNS; 
        break; 
       case MoveType.ResizeWidth: 
        Cursor = Cursors.SizeWE; 
        break; 
      } 
     } 
     #endregion 

     if (mainGrid.Children.Count > 0) 
      this.mainGrid.Children.RemoveAt(0); 
     Rectangle r = new Rectangle(); 
     p_End = e.GetPosition(null); 
     switch (move) 
     { 
      case MoveType.Draw:          
       r.Stroke = new SolidColorBrush(Colors.Aqua); 
       r.Opacity = 1; 
       r.Height = Math.Abs(p_End.Y - p_Start.Y); 
       r.Width = Math.Abs(p_End.X - p_Start.X); 
       double t_left = p_End.X > p_Start.X ? p_Start.X : p_End.X; 
       double t_top = p_End.Y > p_Start.Y ? p_Start.Y : p_End.Y; 
       r.VerticalAlignment = VerticalAlignment.Top; 
       r.HorizontalAlignment = HorizontalAlignment.Left; 
       r.Margin = new Thickness(t_left, t_top, 0, 0); 
       this.mainGrid.Children.Add(r); 
       saveRect = r; 
       break; 
      case MoveType.Drag: 
       r = saveRect; 
       double moveHorizontal = p_Start.X - p_End.X; 
       double moveVertical = p_Start.Y - p_End.Y; 
       if (r.Margin.Left - moveHorizontal < 0) 
        moveHorizontal = r.Margin.Left; 
       if (r.Margin.Top - moveVertical < 0) 
        moveVertical = r.Margin.Top; 
       r.Margin = new Thickness(r.Margin.Left - moveHorizontal, r.Margin.Top - moveVertical, 0, 0); 
       this.mainGrid.Children.Add(r); 
       saveRect = r; 
       p_Start = p_End; 
       break; 
      case MoveType.ResizeHeight: 
       r = saveRect; 
       double resize = p_Start.Y - p_End.Y; 
       if (top) 
       {      
        r.Margin = new Thickness(r.Margin.Left, r.Margin.Top - resize, 0, 0);       
        r.Height += resize; 
       } 
       else 
       {      
        r.Height -= resize; 
       } 
       this.mainGrid.Children.Add(r); 
       saveRect = r; 
       p_Start = p_End; 
       break; 
      case MoveType.ResizeWidth: 
       r = saveRect; 
       double resizeX = p_Start.X - p_End.X; 
       if (left) 
       { 
        r.Margin = new Thickness(r.Margin.Left - resizeX, r.Margin.Top, 0, 0); 
        r.Width += resizeX; 
       } 
       else 
       { 
        r.Width -= resizeX; 
       } 
       this.mainGrid.Children.Add(r); 
       saveRect = r; 
       p_Start = p_End; 
       break; 
     } 
    } 

    private void Window_MouseRightButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     RaiseCustomEvent(this, new customEventArgs(getPoints())); 
     this.Close(); 
    } 

    public List<Point> getPoints() 
    { 
     List<Point> p = new List<Point>(); 
     this.Visibility = Visibility.Collapsed; 
     if (mainGrid.Children.Count > 0) 
     { 
      p.Add(new Point(saveRect.Margin.Left, saveRect.Margin.Top)); 
      p.Add(new Point(saveRect.Width+ saveRect.Margin.Left, saveRect.Height+ saveRect.Margin.Top)); 
      return p; 
     } 

     return null; 
    } 

    private bool between(double actual, double min, double max) 
    { 
     if ((actual < min) || (actual > max)) 
      return false; 
     else return true; 
    } 

    private enum MoveType 
    { 
     Draw, 
     Drag, 
     ResizeHeight, 
     ResizeWidth 
    } 

} 

public class customEventArgs : EventArgs 
{ 
    private List<Point> pts; 
    public customEventArgs(List<Point> Points) 
    { 
     pts = Points; 
    } 

    public List<Point> Points 
    { 
     get { return pts; } 
    } 
} 

二次ウィンドウのXAML:

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:WpfApplication1" 
    mc:Ignorable="d" 
    Title="W1" Height="300" Width="300" WindowStyle="None" Topmost="True" BorderThickness="0" Foreground="{x:Null}" AllowsTransparency="True" 
    Left="0" Top="0" 
    MouseLeftButtonDown="Window_MouseLeftButtonDown" Loaded="Window_Loaded" MouseMove="Window_MouseMove" MouseRightButtonDown="Window_MouseRightButtonDown" 
    MouseLeftButtonUp="Window_MouseLeftButtonUp" > 
<Window.Background> 
    <SolidColorBrush Opacity="0.3" Color="Gray"></SolidColorBrush> 
</Window.Background> 
<Grid Name="mainGrid">   
</Grid> 

だから、ここに私の質問は以下のとおりです。

  1. なぜ窓ないピクセル単位で実際のサイズの大きさは?
  2. 私が撮った画像に、それほど欲しくないすべての機能が含まれるように、私が望む値を得るにはどうすればよいですか?

ありがとうございました。

+0

は、ピクセルではなく、ディップ(デバイスに依存しない単位)です。詳細情報[ここをクリック](https://msdn.microsoft.com/en-us/library/windows/desktop/ff684173(v = vs.85).aspx) – Pikoh

+0

120 DPIのディスプレイを使用している場合や、 96 DPIディスプレイでウィンドウのテキストサイズを125%にすると、ピクセルはWPFのデバイスに依存しないピクセルと1,25倍になります。 – haindl

+0

@ピコ:ありがとう、そのリンクともう少し多くの検索が助けてくれました – Thoms

答えて

0

ピコのリンクが正しい方向だった。 は差が(100+ピクセル)十分な大きさであるとき(理由を知っているドント)私はオフ1つのまたは2ピクセルまだだこのHow can I get the DPI in WPF?

private double getDPIScale() 
    { 
     PresentationSource source = PresentationSource.FromVisual(this); 

     double dpiX , dpiY; 
     if (source != null) 
     { 
      dpiX = 96.0 * source.CompositionTarget.TransformToDevice.M11; 
      dpiY = 96.0 * source.CompositionTarget.TransformToDevice.M22; 
      return dpiX/96.0; 
     } 

     return 0;    
    } 

に私を導いたが、私はそれと一緒に暮らすことができます。

編集:違いは約8ピクセルです。いつもそこにあります - それはウィンドウの境界線などと思われます。

デフォルトでWpfサイズの
関連する問題