반응형

OpenGL 화면에 Pygame 이미지(스프라이트)를 렌더링 해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = ((1-1-1), (11-1), (-11-1), (-1-1-1),
             (1-11), (111), (-1-11), (-111))
edges = ((0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4),
         (6,7), (5,1), (5,4), (5,7))
 
def drawCube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def drawImage(x, y):
    image = pygame.image.load("player.png").convert()
    image.set_colorkey(image.get_at((00)))
    image = pygame.transform.scale(image, (image.get_width()*1.5,
                                           image.get_height()*1.5))
    imageData = pygame.image.tostring(image, "RGBA"True)
    glWindowPos2d(x-image.get_width()/2, y-image.get_height()/2)
    glDrawPixels(image.get_width(), image.get_height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, imageData)
 
pygame.init()
clock = pygame.time.Clock()
display = (640480)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
 
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
 
gluPerspective(45, (display[0]/display[1]), 0.150.0)
glTranslatef(0.00.0-5)
 
run = True
while run:    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
 
    glRotatef(1311)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    drawCube()
    drawImage(display[0]/2, display[1]/2)
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
exit()
 

 

 

 

반응형
Posted by J-sean
:
반응형

이미지 파일을 Drag & Drop으로 열어보자.

 

WinForm에 PictureBox를 적당히 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
 
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            pictureBox1.AllowDrop = true;
            // 인텔리센스에는 pictureBox1.AllowDrop가 표시되지 않는다.
            // 하지만 사용은 가능하며 인텔리센스를 사용하고 싶다면 아래처럼
            // Control로 형변환해서 해도 된다.
            // ((Control)pictureBox1).AllowDrop = true;
        }
 
        private void pictureBox1_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }
 
        private void pictureBox1_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                // 드롭된 파일들의 전체 경로명을 반환.
                foreach (string file in files)
                {
                    if (file.EndsWith("jpg"|| file.EndsWith("JPG"))
                    {
                        // JPG 파일만 디스플레이
                        pictureBox1.Image = System.Drawing.Image.FromFile(file);
                    }
                }
            }
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

프로그램을 실행하고 PictureBox 위로 JPG파일을 드래그 & 드롭한다.

 

이미지가 표시된다.

 

반응형
Posted by J-sean
:
반응형

2021.11.29 - [C#] - C# Desktop Capture and Image Display Program - 바탕화면 캡쳐 & 이미지 출력 프로그램

 

바탕화면에 이미지를 출력하는 크리스마스 프로그램 예제.

 

폼, 버튼, 링크 레이블등을 적당히 배치하고 리소스를 등록한다.

 

Images.zip
2.28MB

폼에는

FormBorderStyle - None

ShowInTaskBar - False

TopMost - True

등의 조건을 준다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using System.Runtime.InteropServices;
using System.Media;
 
namespace Christmas
{
    public partial class Form1 : Form
    {
        [DllImport("User32.dll")]
        public static extern IntPtr GetDC(IntPtr hwnd);
 
        [DllImport("user32.dll")]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
 
        // 바탕화면 refresh
        [DllImport("Shell32.dll")]
        private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
 
        int screenWidth;
        int screenHeight;
 
        IntPtr desktopPtr;
 
        // 이미지 파일은 화면과 해상도가 달라서 작거나 크게 표시될 수 있다.
        // Image로 받지 말고 비트맵으로 변환해 사용하면 된다.
        Bitmap tree;                
        Bitmap leftTop;
        Bitmap rightTop;
        Bitmap rightDeer;
        Bitmap cane;
        Bitmap bulb;
        Bitmap snowMan;
        Bitmap merry;
 
        public Form1()
        {
            InitializeComponent();
 
            screenWidth = Screen.PrimaryScreen.Bounds.Width;
            screenHeight = Screen.PrimaryScreen.Bounds.Height;
 
            desktopPtr = GetDC(IntPtr.Zero);
 
            tree = new Bitmap(Properties.Resources.tree1);
            rightDeer = new Bitmap(Properties.Resources.RightDeer);
            leftTop = new Bitmap(Properties.Resources.LeftTop);
            rightTop = new Bitmap(Properties.Resources.RightTop);
            cane = new Bitmap(Properties.Resources.cane);
            bulb = new Bitmap(Properties.Resources.bulb);
            snowMan = new Bitmap(Properties.Resources.BottomSnowMan);
            merry = new Bitmap(Properties.Resources.Merry);
        }
 
        ~Form1()
        {
            ReleaseDC(IntPtr.Zero, desktopPtr);
        }
        
        private void Form1_Load(object sender, EventArgs e)
        {
            // 폼의 시작 위치를 생성자에서 설정하면 크기가 줄어드는 등 비정상적으로 동작한다.
            StartPosition = FormStartPosition.Manual;
            Location = new Point(screenWidth - Size.Width, screenHeight - Size.Height - 40);
 
            // Gets or sets a value indicating whether the form will receive key events before the event is passed
            // to the control that has focus.
            // true if the form will receive all key events; false if the currently selected control on the form
            // receives key events. The default is false.
            // 키가 눌렸을때 포커스를 갖고 있는 컨트롤보다 폼이 먼저 키 이벤트를 받을 수 있게 한다. 단축키 지정을 위해.
            KeyPreview = true;
 
            // 타이머를 작동시키면 반투명 이미지 부분이 계속 진해진다. 필요하면 작동시키자.
            //timer1.Enabled = true;
 
            SoundPlayer p = new SoundPlayer();
            p.Stream = Properties.Resources.Song;
            p.Play();
            
            using (Graphics g = Graphics.FromHdc(desktopPtr))
            {
                g.DrawImage(bulb, screenWidth - rightDeer.Width - bulb.Width, 0);
                g.DrawImage(leftTop, 00);
                g.DrawImage(rightTop, screenWidth - rightTop.Width, 0);
                g.DrawImage(rightDeer, screenWidth - rightDeer.Width, (screenHeight - rightDeer.Height) / 2);
                g.DrawImage(cane, cane.Width / 4, (screenHeight - cane.Height) / 2);                
                g.DrawImage(snowMan, 0, screenHeight - snowMan.Height);
                g.DrawImage(merry, screenWidth - merry.Width, screenHeight - merry.Height - 40);
                g.DrawImage(tree, (screenWidth - tree.Width) / 240);
            }
        }
 
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
 
                case Keys.Q:
                    Close();
                    break;
 
                case Keys.R:
                    Reload();
                    break;
 
                case Keys.H:
                    System.Diagnostics.Process.Start("https://s-engineer.tistory.com/");
                    break;
 
                default:
                    break;
            }
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            Close();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            Reload();
        }
        private void Reload()
        {
            using (Graphics g = Graphics.FromHdc(desktopPtr))
            {
                g.DrawImage(bulb, screenWidth - rightDeer.Width - bulb.Width, 0);
                g.DrawImage(leftTop, 00);
                g.DrawImage(rightTop, screenWidth - rightTop.Width, 0);
                g.DrawImage(rightDeer, screenWidth - rightDeer.Width, (screenHeight - rightDeer.Height) / 2);
                g.DrawImage(cane, cane.Width / 4, (screenHeight - cane.Height) / 2);
                g.DrawImage(snowMan, 0, screenHeight - snowMan.Height);
                g.DrawImage(merry, screenWidth - merry.Width, screenHeight - merry.Height - 40);
                g.DrawImage(tree, (screenWidth - tree.Width) / 240);
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            using (Graphics g = Graphics.FromHdc(desktopPtr))
            {
                g.DrawImage(bulb, screenWidth - rightDeer.Width - bulb.Width, 0);
                g.DrawImage(leftTop, 00);
                g.DrawImage(rightTop, screenWidth - rightTop.Width, 0);
                g.DrawImage(rightDeer, screenWidth - rightDeer.Width, (screenHeight - rightDeer.Height) / 2);
                g.DrawImage(cane, cane.Width / 4, (screenHeight - cane.Height) / 2);
                g.DrawImage(snowMan, 0, screenHeight - snowMan.Height);
                g.DrawImage(merry, screenWidth - merry.Width, screenHeight - merry.Height - 40);
                g.DrawImage(tree, (screenWidth - tree.Width) / 240);
            }
        }
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 바탕화면 refresh
            SHChangeNotify(0x80000000x1000IntPtr.Zero, IntPtr.Zero);
        }
 
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            linkLabel1.LinkVisited = true;
            System.Diagnostics.Process.Start("https://s-engineer.tistory.com/");
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

실행하면 바탕화면에 이미지가 표시된다.

 

반응형
Posted by J-sean
:
반응형

이미지 파일을 어떻게 불러오는지에 따라 해상도가 다르게 적용될 수 있다.

 

Reindeer.png
0.08MB

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Image i = Image.FromFile("Reindeer.png");
            Bitmap b1 = (Bitmap)Bitmap.FromFile("Reindeer.png");
            Bitmap b2 = new Bitmap(Image.FromFile("Reindeer.png"));
            
            // 100 pixel 간격
            e.Graphics.DrawImage(i, 00);
            e.Graphics.DrawImage(b1, 1000);
            e.Graphics.DrawImage(b2, 2000);
 
            // 해상도 출력
            string str = string.Format("i: {0}X{1}, b1: {2}X{3}, b2: {4}X{5}", i.HorizontalResolution, i.VerticalResolution,
                b1.HorizontalResolution, b1.VerticalResolution, b2.HorizontalResolution, b2.VerticalResolution);
            e.Graphics.DrawString(str, Font, Brushes.Black ,100510);
        }
    }
}
 

 

같은 파일(Reindeer.png)을 세 가지 방법으로 불러와서 100 픽셀 간격으로 출력해 보자.

 

i, b1과 b2의 해상도가 다르다.

 

예상한 것과 다른 방식으로 출력된다. 다른 이미지 뷰어에 표시되는 사이즈와 동일한 방식은 b2다. i, b1은 약간 확대(96/72=1.3배) 되었다. 이미지 파일을 사용할 때는 어떤식으로 불러올지 잘 선택하자.

 

파일에 따라 어떻게 불러와도 같은 사이즈로 표시되기도 한다.

 

반응형
Posted by J-sean
:
반응형

바탕화면에 이미지를 출력하고 움직여 보자.

 

폼과 버튼을 적당히 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
using System.Runtime.InteropServices;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        private static extern IntPtr GetDC(IntPtr hWnd);
 
        [DllImport("user32.dll", ExactSpelling = true)]
        private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            int step = 1;   // 이동 스텝
 
            Rectangle targetRect = new Rectangle(100150400400);   // 표시할 그림 사이즈(Horizontal: 100~499(400) pixel, Vertical: 150~549(400) pixel) 
            Point outPoint = new Point(500300);   // 모니터의 표시 위치(x, y)
 
            //Image img = Image.FromFile("Barbara.jpg");  // Resolution Horizontal: 300, Vertical: 300  
            // 이렇게 하면 이미지 파일과 아래 buffer 비트맵의 해상도(96, 96)가 달라서 (사이즈가) 제대로 표시되지 않는다.
            Bitmap img = new Bitmap(Image.FromFile("Barbara.jpg")); // Resolution Horizontal: 96, Vertical: 96
            Bitmap scr = ScreenCapture.Capture();
            Bitmap buffer = new Bitmap(targetRect.Width + step, targetRect.Height + step);
            IntPtr desktopDC = GetDC(IntPtr.Zero);
 
            Graphics dG = Graphics.FromHdc(desktopDC);
            Graphics bG = Graphics.FromImage(buffer);
            
            for (int i = 0, j = 0; i < 100; i += step, j += step)
            {
                bG.DrawImage(scr, 00new Rectangle(outPoint.X + i, outPoint.Y + j, targetRect.Width + step , targetRect.Height + step ), GraphicsUnit.Pixel);
                bG.DrawImage(img, step, step, targetRect, GraphicsUnit.Pixel);                
                dG.DrawImage(buffer, outPoint.X + i, outPoint.Y + j);
            }
 
            for (int i = 100, j = 100; i > 0; i -= step, j -= step)
            {
                bG.DrawImage(scr, 00new Rectangle(outPoint.X + i, outPoint.Y + j, targetRect.Width + step, targetRect.Height + step), GraphicsUnit.Pixel);
                bG.DrawImage(img, 00, targetRect, GraphicsUnit.Pixel);
                dG.DrawImage(buffer, outPoint.X + i, outPoint.Y + j);
            }
 
            dG.Dispose();
            bG.Dispose();
            ReleaseDC(IntPtr.Zero, desktopDC);
        }
    }
 
    public class ScreenCapture
    {
        [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
        private static extern IntPtr GetDC(IntPtr hWnd);
 
        [DllImport("user32.dll", ExactSpelling = true)]
        private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
 
        [DllImport("gdi32.dll", ExactSpelling = true)]
        private static extern IntPtr BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
 
        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        private static extern IntPtr GetDesktopWindow();
 
        public static Bitmap Capture()
        {
            int screenWidth = Screen.PrimaryScreen.Bounds.Width;
            int screenHeight = Screen.PrimaryScreen.Bounds.Height;
 
            Bitmap screenBmp = new Bitmap(screenWidth, screenHeight);
            Graphics g = Graphics.FromImage(screenBmp);
 
            IntPtr desktopDC = GetDC(GetDesktopWindow());
            IntPtr hDC = g.GetHdc();
 
            BitBlt(hDC, 00, screenWidth, screenHeight, desktopDC, 000x00CC0020);    //SRCCOPY (DWORD)0x00CC0020
 
            ReleaseDC(GetDesktopWindow(), desktopDC);
            g.ReleaseHdc(hDC);
            g.Dispose();
 
            return screenBmp;
        }
    }
}
 

 

소스를 입력하고 빌드한다.

Barbara.jpg
0.05MB

 

실행하고 버튼을 클릭한다.

 

지정된 위치에 이미지가 출력되고 움직인다.

 

반응형
Posted by J-sean
:
반응형

리눅스(우분투)에서 GTK+를 이용해 이미지를 디스플레이 해 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <gtk/gtk.h>
 
static gboolean button_press_callback(GtkWidget* event_box, GdkEventButton* event, gpointer data)
{
    g_print("Event box clicked at coordinates %f,%f\n", event->x, event->y);
 
    return TRUE;
}
 
static void activate(GtkApplication* app, gpointer user_data)
{
    GtkWidget* window;
    GtkWidget* image;
    GtkWidget* event_box;
 
    window = gtk_application_window_new(app);
    gtk_window_set_title(GTK_WINDOW(window), "Window");
    gtk_window_set_default_size(GTK_WINDOW(window), 300300);
 
    event_box = gtk_event_box_new();
    gtk_container_add(GTK_CONTAINER(window), event_box);
 
    image = gtk_image_new_from_file("Barbara Palvin.jpg");
    gtk_container_add(GTK_CONTAINER(event_box), image);
 
    g_signal_connect(G_OBJECT(event_box), "button_press_event", G_CALLBACK(button_press_callback), image);
 
    gtk_widget_show_all(window);
}
 
int main(int argc, char** argv)
{
    GtkApplication* app;
    int status;
 
    app = gtk_application_new("sean.s-engineer.example", G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
    status = g_application_run(G_APPLICATION(app), argc, argv);
    g_object_unref(app);
 
    return status;
}
 
 
 

 

컴파일(빌드)하고 실행하면 창에 이미지가 디스플레이 된다. 클릭하면 좌표가 터미널에 표시된다.

 

반응형
Posted by J-sean
:
반응형

2021.01.04 - [Linux] - Open Image Files From Terminal in Linux(Ubuntu) - 리눅스(우분투) 터미널에서 이미지 파일 열기

 

리눅스(우분투) 서버 같은 콘솔 환경에서도 이미지 뷰어를 사용할 수 있다.

 

fbi를 설치한다. fbi는 리눅스의 framebuffer를 이용해 이미지를 디스플레이한다. 

 

sudo fbi '이미지 파일' 형식으로 실행한다.

 

이미지가 디스플레이 된다.

 

h키를 누르면 keyboard commands를 볼 수 있다.

 

반응형
Posted by J-sean
:
반응형

보통 이미지 뷰어는 투명 영역을 체크무늬나 검정색으로 표시한다. 이미지의 투명한 영역이 투과되어 보이는 이미지 뷰어를 사용해 보자.


투명 배경에 흰색 글자가 표시되어 있다. 흰색 배경의 브라우저를 사용한다면 위 이미지가 보이지 않는다.


pqiv를 설치한다.


pqiv -c -i -P '50, 50' sean.png 명령을 실행한다. '&' 옵션을 주지 않아도 백그라운드로 실행된다.


-c, --transparent-background

Draw pqiv's window borderless and transparent. In window mode, a mouse click activates and deactivates window decorations.


-i, --hide-info-box

Initially hide the infobox. Whether the box is visible can be toggled by pressing 'i' at runtime by default.


-P, --window-position=POSITION

Set the initial window position. POSITION may either be 'x,y'  screen coordinates or 'off' to not position the window at all.


그 외 옵션은 Ubuntu Manpage를 참고하자.


반응형
Posted by J-sean
: