0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

キャプチャアプリ (印刷版)

Last updated at Posted at 2025-07-19
  • 印刷版です。通常使用するプリンタに出力されます
  • 先に通常使用するプリンタを指定しておきます
  • 使用法はJPG保存版と同じです
  • 印字サイズは用紙にあわせて自動的に最適化します
  • どんなに大きくキャプチャしても縮小して全て印刷されますが逆に小さいと用紙いっぱいに拡大する為、見づらくなります
  • Process.Start()で標準APP利用して印刷とようと思ったもののどうやっても例外消えず諦め

1.WPF (C#)

//////////////////////////////////////////////////////
// CAP2PRN R1.00 (WPF and .Netframework)
// ReachFramework , System.Printing
// System.Drawing , System.Windows.Forms 参照設定
// (c)inf102 S.H. 2025. All rights reserved.
//////////////////////////////////////////////////////

using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace PRN01 {

    public partial class MainWindow : Window {

        [DllImport("User32.dll")]
        private static extern bool SetCursorPos(int X, int Y);

        ///////////////////////////////////////////////////////////////////////////////////////////
        const int WAKU=3;               // 選択枠の幅
        static string Desktop="";
        static int x1=0,y1,x2,y2;
        static bool area_select=false;  // false = 選択開始前 , true = エリア選択中
        static int Y=0;
        ///////////////////////////////////////////////////////////////////////////////////////////

        public void m(string s) {
            MessageBox.Show(s);
        }

        public  MainWindow() {
            InitializeComponent();
            
            // デスクトップにND_SSフォルダ作成
            Desktop=System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            Directory.CreateDirectory(Desktop+"\\ND_SS");
            Desktop+="\\ND_SS";

            // 画面全体のスクリーンショット保存
            BitmapSource bs=FULLCopyScreen();
            using (Stream stream = new FileStream (Desktop+"\\ND_SSTMP.JPG", FileMode.Create)){
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(bs));
                encoder.Save(stream);    
            }

            // マウス十字型に変更
            Mouse.OverrideCursor = Cursors.Cross;

            // マウスカーソルをプライマリディプレイの中央に移動
            SetCursorPos((int)SystemParameters.PrimaryScreenWidth/2,(int)SystemParameters.PrimaryScreenHeight/2);      
        }

        // 選択前
        public void Msg1(object sender) {
            var canvas = sender as Canvas;    
            SolidColorBrush brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255,255, 0, 0));
            TextBlock text2 = new TextBlock{
                Text = "[印刷] マウス左押して選択開始.\r\n何かキー押すと中止. [HOME]で全画面印刷",
                FontSize = 21,
                Foreground = brush,
                FontWeight = FontWeights.Bold
            };

            // X軸設定 //////////////
            bool FLG = false;
            
            // 左端
            if (x2 < 180) {
                Canvas.SetLeft(text2,10);
                FLG = true;
            }

            // 右端
            if (x2>(int)SystemParameters.PrimaryScreenWidth -200) {
                Canvas.SetLeft(text2,(int)SystemParameters.PrimaryScreenWidth-370);
                FLG=true;
            }
            
            // 通常
            if (FLG==false) Canvas.SetLeft(text2,x2-170 );
            /////////////////////////////////////////////////////////////////////////

            /////////////////////////
            // Y軸設定 //////////////
            ////////////////////////
            // マウスが下より上
            if ( Y==0 && (y2 < (int)SystemParameters.PrimaryScreenHeight-70)) Canvas.SetTop(text2,y2+20);
       
            // マウスが下の下 は必ず上表示
            if ( y2 > (int)SystemParameters.PrimaryScreenHeight-70 ){
                Canvas.SetTop(text2,y2-70);
                Y=2;
            }

            // マウスが上より下で上に表示中 
            if ( Y==2 && (y2 > 70)) Canvas.SetTop(text2,y2-70);
                     
            // マウスが上の上
            if ( y2 < 70 ){
                Canvas.SetTop(text2,y2+20);
                Y=0;
            }

            // 下に表示中でマウスが画面より下
            if ( Y==0 && y2  > (int)SystemParameters.PrimaryScreenHeight-70 ){
                Canvas.SetTop(text2,y2+20);
                Y=5;
            }

            // 上に表示中 上より下
            if (Y == 5 && y2 > 70) Canvas.SetTop(text2,y2-70);
        
            // 文字表示
            DrawCanvas.Children.Add(text2);
        
        }

        // 選択中
        public void Msg2(object sender) {
            if (Math.Abs(x2-x1) <380) return;
            if (Math.Abs(y2-y1) <60) return;

            var canvas = sender as Canvas;
            DrawCanvas.Children.Clear();
                      
            SolidColorBrush brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255,0, 255, 0));
            TextBlock text = new TextBlock{
                Text = "印刷範囲 指定中.左Upで印刷\r\n何かキー押すと中止. [HOME]で全画面印刷",
                FontSize = 21,
                FontWeight= FontWeights.Bold,
                Foreground = brush
            };
            
            Canvas.SetLeft(text,(x2-x1)/2+x1-185);
            Canvas.SetTop (text,(y2-y1)/2+y1-30 );
            DrawCanvas.Children.Add(text);
        }

        // 選択開始
        private void Window_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) {
            var canvas = sender as Canvas;
            area_select=true;

            // 選択開始位置          
            System.Windows.Point position = e.GetPosition(canvas);
            x1=(int)position.X;
            y1=(int)position.Y;
            
            Msg2(sender);                  
        }

        // 領域枠表示 マウス移動イベント
        private void Window_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e) {
            DrawCanvas.Children.Clear();

            var canvas = sender as Canvas;
            System.Windows.Point position = e.GetPosition(canvas);       

            // MOUSE XY
            x2=(int)position.X;
            y2=(int)position.Y;

            SolidColorBrush brush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255,255, 0, 0));

            // 選択開始表示 左ボタン前
            if (area_select==false) {
                Msg1(sender);
                return;
            }
                                   
            // 範囲選択中の説明表示
            Msg2(sender);

            Line Line1 = new Line();
            Line Line2 = new Line();
            Line Line3 = new Line();
            Line Line4 = new Line();
                               
            Line1.MouseUp += Window_PreviewMouseLeftButtonUp;
            Line2.MouseUp += Window_PreviewMouseLeftButtonUp;
            Line3.MouseUp += Window_PreviewMouseLeftButtonUp;
            Line4.MouseUp += Window_PreviewMouseLeftButtonUp;
             
            Line1.Stroke = System.Windows.Media.Brushes.Yellow;
            Line1.StrokeThickness = WAKU;    // 線の太さ

            Line2.Stroke = System.Windows.Media.Brushes.Yellow;
            Line2.StrokeThickness = WAKU;    

            Line3.Stroke = System.Windows.Media.Brushes.Yellow;
            Line3.StrokeThickness = WAKU;    

            Line4.Stroke = System.Windows.Media.Brushes.Yellow;
            Line4.StrokeThickness = WAKU;  
            
            // 左上から左下
            Line1.X1 = x1; // 開始点X
            Line1.Y1 = y1; // 開始点Y
            Line1.X2 = x1; // 終了点X
            Line1.Y2 = y2; // 終了点Y

            // Canvas に追加
            DrawCanvas.Children.Add(Line1);

            // 左上から右上
            Line2.X1 = x1;  // 開始点X
            Line2.Y1 = y1;  // 開始点Y
            Line2.X2 = x2;  // 終了点X
            Line2.Y2 = y1;  // 終了点Y
            DrawCanvas.Children.Add(Line2);

            //左下から右下
            Line3.X1 = x1;  // 開始点X
            Line3.Y1 = y2;  // 開始点Y
            Line3.X2 = x2;  // 終了点X
            Line3.Y2 = y2;  // 終了点Y

            // Canvas に追加
            DrawCanvas.Children.Add(Line3);

            //右上から右下
            Line4.X1 = x2;  // 開始点X
            Line4.Y1 = y1;  // 開始点Y
            Line4.X2 = x2;  // 終了点X
            Line4.Y2 = y2;  // 終了点Y

            // Canvas に追加
            DrawCanvas.Children.Add(Line4);
        }

        // 選択完了
        private  void Window_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) {
                            
            int xx=x1,yy=y1,he=y2-y1,wi=x2-x1;

            // FILENAME
            string outfile=DateTime.Now.ToString("yyMMdd-HH-mm-ss");

            // 左上から右下
            if (x1 < x2 && y1 < y2) {
                CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", xx,yy,wi,he);
            }

            // 右下から左上
            if (x1 > x2 && y1 > y2){
                xx=x2;
                yy=y2;
                wi=Math.Abs(wi);
                he=Math.Abs(he);
                CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", xx-10,yy-7,wi+5,he+2);
            }
            
            // 左下から右上 
            if (x1 < x2 && y1 > y2) {
                wi=x2-x1;
                he=y1-y2;
                yy=y2;
                CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", xx-10,yy-7,wi+5,he+2);
            }

            // 右上から左下
            if (y1 < y2 && x1 > x2){
                yy=y1;
                wi=x2-x1;
                wi=Math.Abs(wi);
                he=y2-y1;
                xx=x2;
                CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", xx-10,yy-7,wi+5,he+2);
            }

            // 切り抜き部を横向き用紙に合わせて拡大・縮小して印刷          
            BitmapImage bmp = new BitmapImage(new Uri(Desktop+"\\"+outfile+".jpg"));
            PrintImage(bmp);
              
            // 一時ファイル削除
            File.Delete(Desktop+"\\ND_SSTMP.JPG");
            
            // 印刷 mspaint使用
            /*
            System.Threading.Thread.Sleep(500);
            ProcessStartInfo psi = new ProcessStartInfo{
                FileName = "mspaint.exe",
                Arguments = "/p "+ Desktop+"\\"+outfile+".jpg",
                CreateNoWindow = true,
                WindowStyle = ProcessWindowStyle.Hidden
            };

            Process.Start(psi);
            */

            Application.Current.Shutdown();
        }

         // 全画面印刷 or 中止 
        private void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) {
            // 全画面
            if (e.Key == Key.Home){
                string outfile=DateTime.Now.ToString("yyMMdd-HH-mm-ss");
                CropJpeg(Desktop+"\\ND_SSTMP.JPG", Desktop+"\\"+outfile+".jpg", 0,0,(int)SystemParameters.PrimaryScreenWidth-1,(int)SystemParameters.PrimaryScreenHeight-1);

                BitmapImage bmp = new BitmapImage(new Uri(Desktop+"\\"+outfile+".jpg"));
                PrintImage(bmp);
            }

            try {
                File.Delete(Desktop+"\\ND_SSTMP.JPG");
            }
            catch{ }

            Application.Current.Shutdown();

        }

        // 部分カット
        public void CropJpeg(string inputPath, string outputPath, int x, int y, int width, int height){
            BitmapImage source = new BitmapImage();
            source.BeginInit();
            source.UriSource = new Uri(inputPath, UriKind.Absolute);
            source.CacheOption = BitmapCacheOption.OnLoad;
            source.EndInit();
                        
            var rect = new System.Drawing.Rectangle((int)this.Left, (int)this.Top, (int)this.Width, (int)this.Height);
            var screen = System.Windows.Forms.Screen.FromRectangle(rect);
            
            int w = screen.Bounds.Width;
            int h = screen.Bounds.Height;
            if (x+width >=w) width  =w-x;
            if (y+height>=h) height =h-y;
            if (y<0) y=0;
            if (x<0) x=0;
            if (width  >w) width =w;
            if (height >h) height=h;

            Int32Rect cropArea = new Int32Rect(x, y, width, height);
            
            CroppedBitmap cropped=null;
            try{
                cropped = new CroppedBitmap(source, cropArea);
                JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(cropped));

                using (FileStream fs = new FileStream(outputPath, FileMode.Create)){
                    encoder.Save(fs);
                    fs.Close();
                }  
            }
            catch {
                cropped =null;
                m("範囲が狭すぎます.やり直して下さい.");
                Application.Current.Shutdown();
            }     
        }

        // FULLSCREEN CAPTURE
        private static BitmapSource FULLCopyScreen(){
            using (var screenBmp = new Bitmap((int)SystemParameters.PrimaryScreenWidth,(int)SystemParameters.PrimaryScreenHeight,System.Drawing.Imaging.PixelFormat.Format32bppArgb)){
                using (var bmpGraphics = Graphics.FromImage(screenBmp)){
                    bmpGraphics.CopyFromScreen(0, 0, 0, 0, screenBmp.Size);
                    return Imaging.CreateBitmapSourceFromHBitmap(screenBmp.GetHbitmap(),IntPtr.Zero,Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());
                }
            }
        }
       
        // 用紙に合わせて印字
        public void PrintImage(BitmapImage bitmapImage){
            byte[] imageData;
            JpegBitmapEncoder encoder = new JpegBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
            using (MemoryStream ms = new MemoryStream()){
                encoder.Save(ms);
                imageData = ms.ToArray();
            }

            System.Drawing.Image imageToPrint;
            using (MemoryStream ms = new MemoryStream(imageData)){
                imageToPrint = System.Drawing.Image.FromStream(ms);
            }

            PrintDocument printDoc = new PrintDocument();
            printDoc.DefaultPageSettings.Landscape = true;
            printDoc.PrintPage += (s, e) =>{
                System.Drawing.Rectangle bounds = e.MarginBounds;

                float scale = Math.Min((float)bounds.Width / imageToPrint.Width,(float)bounds.Height / imageToPrint.Height);
                int width = (int)(imageToPrint.Width * scale);
                int height = (int)(imageToPrint.Height * scale);
                int left = bounds.Left + ((bounds.Width - width) / 2);
                int top = bounds.Top + ((bounds.Height - height) / 2);
                        
                e.Graphics.DrawImage(imageToPrint, left, top, width, height);
            };
            printDoc.Print();
        }
    }
}

2.WPF (XAML)

<Window x:Class="PRN01.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:PRN01" mc:Ignorable="d" Background="#50000000" AllowsTransparency="True" ShowInTaskbar="False" WindowStyle="None"
        WindowState="Maximized" PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown" PreviewMouseMove="Window_PreviewMouseMove" PreviewKeyDown="Window_PreviewKeyDown"  >
        
    <Grid x:Name="G1" >
        <Canvas Name="DrawCanvas"  >
        </Canvas>
    </Grid>
</Window>       
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?