๋ฐ˜์‘ํ˜•

์ด๋ฏธ์ง€ ๋ทฐ์–ด(Image Viewer)

๋น„์ „ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ด๋ฏธ์ง€ ๋ทฐ์–ด๋Š” ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ทจ๋“๋˜๋Š” ์นด๋ฉ”๋ผ ์˜์ƒ์ด๋‚˜ ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€๋ฅผ ๋„์šฐ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋ณดํ†ต์€ Picture Box๋‚˜ Panel์—๋‹ค๊ฐ€ ๊ทธ๋ฆฌ๊ธฐ ๋งˆ๋ จ์ธ๋ฐ์š”. ๋งŒ์•ฝ, ๋ฌดํ„ฑ๋Œ€๊ณ  ์นด๋ฉ”๋ผ ์˜์ƒ์„ ๋ฐ›๋Š” ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ ๋ฐ˜์‘ ์†๋„์— ์˜ํ–ฅ์„ ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ณ ํ•ด์ƒ๋„์˜ ์ด๋ฏธ์ง€๋ฅผ ์ปจํŠธ๋กค์˜ ํฌ๊ธฐ์— ๋งž์ถฐ Stretch ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๋น ๋ฅธ ์†๋„๋กœ ์ปจํŠธ๋กค์˜ ์ด๋ฏธ์ง€๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ฉด UI ๋ฐ˜์‘ ์†๋„๊ฐ€ ๋Š๋ ค์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋ณดํ†ต์€ ์ด๋Ÿฐ ๊ฑฑ์ •์„ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ๊ทธ๋žจ์€ ์˜์ƒ์„ ์ฒœ์ฒœํžˆ ๋„์šฐ๊ฑฐ๋‚˜ ๋น ๋ฅด๊ฒŒ ๋„์šฐ๋”๋ผ๋„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์„ ์กฐ์ž‘ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋น„์ „ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๊ฐ™์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋‹ค์ˆ˜์˜ ์นด๋ฉ”๋ผ ์˜์ƒ์„ ๋„์šฐ๋ฉด์„œ ์ œ์–ด๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด ์–˜๊ธฐ๊ฐ€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€ ํ™•๋Œ€/์ถ•์†Œ, ๋งˆ์šฐ์Šค Drag & Drop์— ๋”ฐ๋ฅธ ์ด๋™, ์‹ค์‹œ๊ฐ„ ๊ฐฑ์‹ ์— ๋”ฐ๋ผ ์‘๋‹ต ์†๋„๊ฐ€ ๋Š๋ ค์ง€๋ฉด ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ๋Š” ์ฐธ์œผ๋กœ ๋‹ต๋‹ตํ•˜๊ณ  ์‹ ๋ขฐ์„ฑ์ด ๋–จ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์„œ๋ก ์ด ๊ธธ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ณธ๋ฌธ์—์„œ๋Š” ์ด๋ฏธ์ง€ ๋ทฐ์–ด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐœ๋ฐœํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ImageGlass ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์žฅ์ ์ด ๋ฌด์—‡์ด๊ณ  ์–ผ๋งˆ๋‚˜ ๊ฐœ๋ฐœํ•˜๊ธฐ ํŽธ๋ฆฌํ•ด์ง€๋Š”์ง€ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ง์ ‘ ์ด๋ฏธ์ง€ ๋ทฐ์–ด ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

ImageGlass๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ์— ์•ž์„œ, ์ด๋ฏธ์ง€ ๋ทฐ์–ด๋ฅผ ์ง์ ‘ ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋™์ž‘ ์ดํ•ดํ•˜๊ธฐ

์•„๋ž˜์™€ ๊ฐ™์ด 500x500 ํฌ๊ธฐ์˜ ์ด๋ฏธ์ง€์™€ 400x400์˜ ์ปจํŠธ๋กค์ด ์žˆ๋‹ค๊ณ  ์˜ˆ์‹œ๋ฅผ ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆผ-ํŒŒ์ผ๊ณผ-์ปจํŠธ๋กค์˜-ํฌ๊ธฐ
๊ทธ๋ฆผ ํŒŒ์ผ๊ณผ ์ปจํŠธ๋กค์˜ ํฌ๊ธฐ

๊ทธ๋ฆผ ํŒŒ์ผ์˜ ๊ฐ€๋กœ, ์„ธ๋กœ ํฌ๊ธฐ๊ฐ€ ์ปจํŠธ๋กค์˜ ํฌ๊ธฐ๋ณด๋‹ค ํฝ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ๊ทธ๋ฆผ์€ ์ปจํŠธ๋กค์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ทธ๋ ค์ง‘๋‹ˆ๋‹ค.

๊ทธ๋ฆผ์ด-์ปจํŠธ๋กค์—-๊ทธ๋ ค์ง€๋Š”-๋ชจ์Šต
๊ทธ๋ฆผ์ด ์ปจํŠธ๋กค์— ๊ทธ๋ ค์ง€๋Š” ๋ชจ์Šต

์ฆ‰, ์ปจํŠธ๋กค์˜ ์˜์—ญ์„ ๋ฒ—์–ด๋‚œ ๋ถ€๋ถ„์€ ๊ทธ๋ ค์ง€๋ฉด ์•ˆ ๋˜๋ฉฐ, ๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์ด๋‚˜ ์Šคํฌ๋กค ๋ฐ” ์ด๋™์œผ๋กœ ์‹œ์ž‘ offset์ด ์ ์šฉ๋˜์–ด ๊ทธ๋ ค์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‹œ์ž‘ offset์ด ๋ณ€๊ฒฝ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ทธ๋ ค์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€-offset-์ ์šฉ์—-๋”ฐ๋ผ-๊ทธ๋ ค์ง€๋Š”-๋ชจ์Šต
์ด๋ฏธ์ง€ offset ์ ์šฉ์— ๋”ฐ๋ผ ๊ทธ๋ ค์ง€๋Š” ๋ชจ์Šต

๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์— ๋”ฐ๋ผ offset์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” LButtonDown, LButtonUp, MouseMove ์ด๋ฒคํŠธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€๋Š” ๊ทธ๋ฆผ์„ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๊ทธ๋ฆฌ๋Š” ํ•จ์ˆ˜๋งŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋์ž…๋‹ˆ๋‹ค. ๋ฌผ๋ก , ํ•„์š”์— ๋”ฐ๋ผ ํ™•๋Œ€/์ถ•์†Œ ๊ธฐ๋Šฅ๋„ ํ•„์š”ํ•˜๊ณ  ์˜ค๋ฒ„๋ ˆ์ด๊ฐ€ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด์จŒ๋“ , ์ด๊ฒŒ ๋‹ค์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ, ์‹ค์ œ ๊ตฌํ˜„์€ ์–ด๋–ป๊ฒŒ ํ•˜๋Š”์ง€ ์ฝ”๋“œ๋ฅผ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ ํ•˜๊ธฐ

ExamViewer ์ด๋ฆ„์˜ Windows Forms ์•ฑ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

WinForm-ํ”„๋กœ์ ํŠธ-์ƒ์„ฑํ•˜๊ธฐ
WinForm ํ”„๋กœ์ ํŠธ ์ƒ์„ฑํ•˜๊ธฐ

๊ทธ๋ฆฌ๊ณ  ์†”๋ฃจ์…˜ ํŒŒ์ผ์— MyViewer ์ด๋ฆ„์˜ ์ปจํŠธ๋กค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์ปจํŠธ๋กค-๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ-์ƒ์„ฑํ•˜๊ธฐ
์ปจํŠธ๋กค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒ์„ฑํ•˜๊ธฐ

์œ„์™€ ๊ฐ™์ด ๋‘ ๊ฐœ์˜ ํ”„๋กœ์ ํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ชจ์Šต์ด ๋ฉ๋‹ˆ๋‹ค.

๋‘-๊ฐœ์˜-ํ”„๋กœ์ ํŠธ๊ฐ€-์ถ”๊ฐ€๋œ-๋ชจ์Šต
๋‘ ๊ฐœ์˜ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ถ”๊ฐ€๋œ ๋ชจ์Šต

UserControl1.cs์˜ ์ฝ”๋“œ ๊ตฌํ˜„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ฃผ์„์œผ๋กœ ๊ฐ„๋‹จํ•œ ์„ค๋ช…์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyViewer
{
    public partial class UserControl1: UserControl
    {
        Point _leftClick = Point.Empty; //์™ผ์ชฝ ๋งˆ์šฐ์Šค ํด๋ฆญ ์ขŒํ‘œ
        Point _offset = Point.Empty; //๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ offset ๊ณ„์‚ฐ
        Point _lastOffset = new Point(0, 0); //๋งˆ์ง€๋ง‰ offset ๋ณด๊ด€ ์šฉ๋„

        Bitmap _bitmap = null; //ํŒŒ์ผ๋กœ ๋ถˆ๋Ÿฌ์˜จ ์ด๋ฏธ์ง€
        Bitmap _canvas = null; //๋”๋ธ” ๋ฒ„ํผ๋ง์„ ์œ„ํ•œ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€
        SolidBrush _background = new SolidBrush(Color.FromArgb(255, 255, 255)); //๋ฐฐ๊ฒฝ ์ƒ‰์ƒ
        Rectangle _sizeCanvas = new Rectangle(0, 0, 0, 0); //๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ

        Rectangle _sizeSrc = new Rectangle(0, 0, 0, 0); //๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€์— ๊ทธ๋ ค์งˆ ์›๋ณธ ์ด๋ฏธ์ง€์˜ ์œ„์น˜
        Graphics _g = null; //๊ทธ๋ ค์งˆ ์ปจํŠธ๋กค์˜ ํ•ธ๋“ค

        public UserControl1()
        {
            InitializeComponent();

            _canvas = new Bitmap(this.Width, this.Height);

            _sizeCanvas.Width = this.Width;
            _sizeCanvas.Height = this.Height;

            _sizeSrc.X = 0;
            _sizeSrc.Y = 0;
            _sizeSrc.Width = this.Width;
            _sizeSrc.Height = this.Height;

            _g = this.CreateGraphics();
        }

        public void LoadImage(string path)
        {
            _bitmap = (Bitmap)Image.FromFile(path);

            draw(_g);
        }

        private void draw(Graphics g)
        {
            if (_bitmap != null)
            {
                var graphics = Graphics.FromImage(_canvas);

                graphics.FillRectangle(_background, _sizeCanvas);

                _sizeSrc.X = -_offset.X;
                _sizeSrc.Y = -_offset.Y;
                graphics.DrawImage(_bitmap, 0, 0, _sizeSrc, GraphicsUnit.Pixel);

                g.DrawImage(_canvas, 0, 0);
            }
        }

        private void UserControl1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _offset.X = e.Location.X - _leftClick.X;
                _offset.Y = e.Location.Y - _leftClick.Y;

                _offset.X += _lastOffset.X;
                _offset.Y += _lastOffset.Y;

                draw(_g); //CPU ๋ถ€ํ•˜๊ฐ€ ๋†’์Œ
            }
        }

        private void UserControl1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _leftClick = e.Location;
            }
        }

        private void UserControl1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _lastOffset = _offset;
            }
        }
    }
}

์ฝ”๋“œ๋Š” ์•„๋ž˜์˜ ์ฒจ๋ถ€๋œ ํŒŒ์ผ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

ExamViewer.zip
0.02MB

๋งˆ์šฐ์Šค ์™ผ์ชฝ ๋ฒ„ํŠผ์˜ ํด๋ฆญ(Down, Up) ๋™์ž‘๊ณผ ์›€์ง์ž„(Move)์— ๋”ฐ๋ผ offset ์ขŒํ‘œ๊ฐ€ ๊ณ„์‚ฐ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  MouseMove ์ด๋ฒคํŠธ์—์„œ ์™ผ์ชฝ ๋ฒ„ํŠผ์ด ํด๋ฆญ๋˜์–ด ์žˆ๋‹ค๋ฉด(๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ) ์ด๋ฏธ์ง€ ๊ทธ๋ฆฌ๋Š” ์ž‘์—…(draw)๋„ ์‹ค์‹œ๋ฉ๋‹ˆ๋‹ค.

draw() ํ•จ์ˆ˜์—์„œ๋Š” _bitmap์„ ์ปจํŠธ๋กค์— ๋ฐ”๋กœ ๊ทธ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. _bitmap์„ ์ปจํŠธ๋กค์— ๋ฐ”๋กœ ๊ทธ๋ฆฌ๊ฒŒ ๋˜๋ฉด, ์ด๋ฏธ์ง€๋ฅผ ๋ฐฐ๊ฒฝ์— ๊ณ„์† ๋ง๊ทธ๋ฆฌ๊ฒŒ ๋˜์–ด ๋งˆ์šฐ์Šค ์ด๋™์— ๋”ฐ๋ผ ์ž”์ƒ์ด ๋‚จ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ชจ์Šต์ด ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€-์ด๋™์—-๋”ฐ๋ผ-์ž”์ƒ์ด-๋‚จ์€-๋ชจ์Šต
์ด๋ฏธ์ง€ ์ด๋™์— ๋”ฐ๋ผ ์ž”์ƒ์ด ๋‚จ์€ ๋ชจ์Šต

๊ทธ๋ž˜์„œ ์ปจํŠธ๋กค ํฌ๊ธฐ์— ๋งž๋Š” ์ž„์‹œ ๋น„ํŠธ๋งต์ธ _canvas๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋”๋ธ” ๋ฒ„ํผ๋ง์œผ๋กœ ์ž”์ƒ์ด ๋‚จ๋Š” ํ˜„์ƒ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ์œ„ ์ฝ”๋“œ์˜ ๋™์ž‘์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋ทฐ์–ด-๋™์ž‘-ํ™”๋ฉด
๋ทฐ์–ด ๋™์ž‘ ํ™”๋ฉด

์ฃผ์˜ ์‚ฌํ•ญ

๋งˆ์šฐ์Šค๋กœ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ์„ ์‹ฌํ•˜๊ฒŒ ์›€์ง์ด๋ฉด CPU ๋ถ€ํ•˜์œจ์ด ์ƒ๋‹นํžˆ ๋†’์•„์ง€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋ ค์ง€๋Š” ์ด๋ฏธ์ง€๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ์ง€ ์•Š์€ ๊ฒƒ๋„ ๋ง์ด์ฃ . ์œ„ ์˜ˆ์ œ ์ฝ”๋“œ๋Š” MouseMove ์ด๋ฒคํŠธ์— draw()๋ฅผ ํ˜ธ์ถœํ•˜๋‹ค ๋ณด๋‹ˆ, ๋งˆ์šฐ์Šค ์›€์ง์ž„์— ๋”ฐ๋ผ ๋„ˆ๋ฌด ๋งŽ์€ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด ์›์ธ์ž…๋‹ˆ๋‹ค. ๋‚˜์ค‘์—๋Š” ํ™•๋Œ€, ์ถ•์†Œ ๊ธฐ๋Šฅ๋„ ๋„ฃ๋‹ค ๋ณด๋ฉด ๋” ์‹ฌํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฒคํŠธ๋ฅผ ์ค„์ด๋˜ ์–ด๋–ป๊ฒŒ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด๋ฏธ์ง€๋ฅผ ๊ทธ๋ ค๋‚ผ์ง€ ๋ฐฉ๋ฒ•์„ ์ฐพ๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๊ตณ์ด ์ด๋Ÿฐ ๊ณ ๋ฏผ์„ ํ•˜๋ฉด์„œ ์ด๋ฏธ์ง€ ๋ทฐ์–ด๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์žˆ์„๊นŒ์š”? ๋ณธ์ธ์ด ๋‹ค ๋งŒ๋“ค์–ด์„œ ๋‚˜์˜ ๊ฒƒ์„ ๋งŒ๋“ค์–ด ๊ฐ€๋Š” ๊ฒƒ๋„ ์ข‹์ง€๋งŒ, ์šฐ๋ฆฌ์—๊ฒŒ ์‹œ๊ฐ„์€ ๋งŽ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด์ œ ์ด๋Ÿฌํ•œ ๊ฑฑ์ •์„ ํ•  ํ•„์š”๊ฐ€ ์—†๋Š”, ๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ด๋ฏธ์ง€ ๋ทฐ์–ด์ธ ImageGlass๋ฅผ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•œ ์ด๋ฏธ์ง€ ๋ทฐ์–ด, ImageGlass

์ฃผ์š” ํŠน์ง•

ImageGlass๋Š” ์ด๋ฏธ์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์•„์ฃผ ๊ฐ€๋ฒผ์šด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค. ์œˆ๋„์šฐ ์‚ฌ์ง„ ๋ทฐ์–ด์ฒ˜๋Ÿผ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋”๋ธ” ํด๋ฆญํ•˜๋ฉด ๋ฐ”๋กœ ๋„์–ด์ง€๋Š” ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.

ImageGlass-์‚ฌ์ง„-๋ทฐ์–ด
ImageGlass ์‚ฌ์ง„ ๋ทฐ์–ด

์ฃผ์š” ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๋‹ค์–‘ํ•œ ์ด๋ฏธ์ง€ ์คŒ(ํ™•๋Œ€/์ถ•์†Œ) ๋ชจ๋“œ, ๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ์ด๋™ ๊ฐ€๋Šฅ
  • ํด๋ฆฝ๋ณด๋“œ๋กœ๋ถ€ํ„ฐ ์ด๋ฏธ์ง€ ์—ด๊ธฐ ๊ฐ€๋Šฅ
  • 70๊ฐœ ์ด์ƒ์˜ ์ด๋ฏธ์ง€ ํฌ๋งท ์ง€์›
  • gif ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ด๋ฏธ์ง€ ํ”„๋ ˆ์ž„ ์ถ”์ถœ ๋ฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ/์ผ์‹œ ์ค‘์ง€ ๊ฐ€๋Šฅ
  • ์Šฌ๋ผ์ด๋“œ ์‡ผ
  • ์ธ๋„ค์ผ ๋ณด๊ธฐ
  • ๋‹จ์ถ•ํ‚ค ์ง€์›
  • ์นผ๋ผ ์ฑ„๋„ ์„ ํƒ ๊ฐ€๋Šฅ
  • ์ƒ‰์ƒ ๋ฐ ํ”ฝ์…€ ๊ฐ’ ์ถ”์ถœ ๊ฐ€๋Šฅ
  • ์ž๋ฅด๊ธฐ ๊ธฐ๋Šฅ
  • ๋‹ค์–‘ํ•œ ์–ธ์–ด ์ง€์›(ํ•œ๊ตญ์–ด ํฌํ•จ)
  • ์„ค์น˜ํ˜•(installer)/์‹คํ–‰ํ˜•(portable) ์ง€์›

ImageViewer๋Š” ์•„๋ž˜ ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

https://imageglass.org/release/imageglass-8-6-7-13-36

 

ImageGlass 8.6.7.13 | ImageGlass

Download ImageGlass 8.6.7.13

imageglass.org

๊ทธ๋Ÿผ ๊ฐœ๋ฐœํ•˜๋Š” ์ž…์žฅ์—์„œ์˜ ์ฃผ์š” ํŠน์ง•๋„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ์œ„ ์–ธ๊ธ‰ํ•œ ๊ธฐ๋Šฅ๊ณผ ๋™์ผ
  • GNU General Public License Version3
  • ์˜คํ”ˆ ์†Œ์Šค
  • C# ์ง€์›(v8.x: .Net 4.8, v9.0: .Net 6)
  • ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ์ง€์›
  • ImageViewer Control ์ง€์›ํ•˜์—ฌ ์‰ฝ๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

ํ˜น์‹œ GNU GPLv3 ๋ผ์ด์„ ์Šค๊ฐ€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

https://www.olis.or.kr/license/Detailselect.do?lId=1072

 

GNU General Public License version 3.0 (GPLv3)

์ž์œ  ์†Œํ”„ํŠธ์›จ์–ด ์žฌ๋‹จ(FSF)๊ณผ ์ด ์žฌ๋‹จ์˜ GNU ํ”„๋กœ์ ํŠธ์— ์˜ํ•ด ๋ฐฐํฌ๋˜๋ฉฐ GNU ์†Œํ”„ํŠธ์›จ์–ด์— ์ ์šฉ๋˜๋Š” ๊ณต๊ฐœ ์†Œํ”„ํŠธ์›จ์–ด์˜ ๋Œ€ํ‘œ์ ์ธ ๋ผ์ด์„ ์Šค ์ฒด๊ณ„. GNU GPL์ด๋ผ๊ณ ๋„ ํ•˜๋ฉฐ, ์ €์ž‘๊ถŒ(copyright)์˜ ๋ฐ˜๋Œ€๋ผ๋Š” ์˜

www.olis.or.kr

ImageGlass ์†Œ์Šค ์ฝ”๋“œ๋Š” ์•„๋ž˜ ๊ณต์‹ Github ์ฃผ์†Œ์—์„œ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

https://github.com/d2phap/ImageGlass

 

GitHub - d2phap/ImageGlass: ๐Ÿž A lightweight, versatile image viewer

๐Ÿž A lightweight, versatile image viewer. Contribute to d2phap/ImageGlass development by creating an account on GitHub.

github.com

๋”ฐ๋ผ ํ•˜๊ธฐ

ExamImageGlass ์ด๋ฆ„์˜ Windows Forms ์•ฑ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Windows-Forms-ํ”„๋กœ์ ํŠธ-์ƒ์„ฑํ•˜๊ธฐ
Windows Forms ํ”„๋กœ์ ํŠธ ์ƒ์„ฑํ•˜๊ธฐ

ImageGlass ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ dll์„ ์ฐธ์กฐ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ๋นŒ๋“œํ•ด์•ผ ํ•˜์ง€๋งŒ, ์ €๋Š” ์ด ๊ณผ์ •์„ ์ƒ๋žตํ•˜๊ณ  ์‹คํ–‰ ํŒŒ์ผ ๊ฒฝ๋กœ์—์„œ dll์„ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค.

์„ค์น˜-๊ฒฝ๋กœ์˜-ImageGlass.ImageBox.dll-์ฐธ์กฐ-์ถ”๊ฐ€ํ•˜๊ธฐ
์„ค์น˜ ๊ฒฝ๋กœ์˜ ImageGlass.ImageBox.dll ์ฐธ์กฐ ์ถ”๊ฐ€ํ•˜๊ธฐ

๊ทธ๋ฆฌ๊ณ  WinForm์— ImageBox ์ปจํŠธ๋กค์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ, ์ €์˜ ๊ฒฝ์šฐ์—๋Š” Visual Studio์˜ ๋””์ž์ด๋„ˆ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์ฝ”๋“œ๋กœ ์ง์ ‘ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋””์ž์ด๋„ˆ์˜ ์ฝ”๋“œ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

namespace ExamImageGlass
{
    partial class Form1
    {
        //์ƒ๋žต

        private void InitializeComponent()
        {
            this.viewer = new ImageGlass.ImageBoxEx();
            this.btnOpen = new System.Windows.Forms.Button();
            this.SuspendLayout();
            //
            // viewer
            // 
            this.viewer.Location = new System.Drawing.Point(5, 5);
            this.viewer.Name = "viewer";
            this.viewer.Size = new System.Drawing.Size(500, 500);
            this.viewer.Dock = System.Windows.Forms.DockStyle.None;
            // btnOpen
            // 
            this.btnOpen.Location = new System.Drawing.Point(513, 12);
            this.btnOpen.Name = "btnOpen";
            this.btnOpen.Size = new System.Drawing.Size(75, 23);
            this.btnOpen.TabIndex = 0;
            this.btnOpen.Text = "Open";
            this.btnOpen.UseVisualStyleBackColor = true;
            this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(600, 520);
            this.Controls.Add(this.btnOpen);
            this.Controls.Add(this.viewer);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
        }

        private ImageGlass.ImageBoxEx viewer;
        private System.Windows.Forms.Button btnOpen;

        #endregion      
    }
}

Form1.cs์˜ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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.Diagnostics;

namespace ExamImageGlass
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            
            viewer.AllowClickZoom = true; //๋งˆ์šฐ์Šค ํด๋ฆญ์œผ๋กœ ํ™•๋Œ€/์ถ•์†Œ
            viewer.ShowPixelGrid = true; //ํ™•๋Œ€ ์‹œ Pixel Grid ํ™œ์„ฑํ™”ํ•˜๊ธฐ
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                viewer.Image = Image.FromFile(dlg.FileName);
            }
        }
    }
}

ExamImageGlass.zip
0.01MB

์‚ฌ์šฉ ๋ฐฉ๋ฒ•์ด ๋„ˆ๋ฌด ๊ฐ„๋‹จํ•˜์ฃ ? AllowClickZoom์€ ๋งˆ์šฐ์Šค์˜ ์™ผ์ชฝ ๋ฒ„ํŠผ์€ ํ™•๋Œ€, ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์€ ์ถ•์†Œ ๋™์ž‘์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ShowPixelGrid๋Š” ํ™•๋Œ€ ๋ฐฐ์œจ์ด ๋†’์•„์กŒ์„ ๋•Œ Grid๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ์˜ต์…˜์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋™์ž‘ ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ImageGlass-๋™์ž‘-ํ™”๋ฉด
ImageGlass ๋™์ž‘ ํ™”๋ฉด

์˜ˆ์ œ๋กœ ๋งŒ๋“  ๋ทฐ์–ด๋ณด๋‹ค ๋” ๋ถ€๋“œ๋Ÿฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ทธ๋ ค์ง‘๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋งˆ์šฐ์Šค ์ด๋™์ด๋‚˜ ์Šคํฌ๋กค ๋ฐ” ์ด๋™์— ๋”ฐ๋ผ ์ด๋ฏธ์ง€ ์ด๋™๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ํ™•๋Œ€ ๋ฐฐ์œจ์ด ๋†’์„ ๊ฒฝ์šฐ Pixel Grid๊ฐ€ ํ‘œํ˜„๋˜์–ด ๊ตฌ๋ถ„์ด ๋”์šฑ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ์Šคํฌ๋กค ๋ฐ” ์‚ฌ์šฉ์„ ์›์น˜ ์•Š๋Š”๋‹ค๋ฉด ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒ ๋‹ค๋Š” ์˜ต์…˜์„ ์ง€์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ ์˜ˆ์‹œ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ํ™•๋Œ€/์ถ•์†Œ ๋ฐ ์ด๋™ํ•˜๋Š” ๋ชจ์Šต๋งŒ ๋ณด์—ฌ๋“œ๋ ธ๋Š”๋ฐ์š”. ImageGlass ์‚ฌ์ง„ ๋ทฐ์–ด์ฒ˜๋Ÿผ ์ž๋ฅด๊ธฐ ๊ธฐ๋Šฅ์ด๋‚˜ ์ขŒํ‘œ์— ๋”ฐ๋ผ ํ”ฝ์…€ ๊ฐ’์„ ์–ป๋Š” ๊ธฐ๋Šฅ, ์ฑ„๋„ ์ถ”์ถœ ๋“ฑ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ฐ˜์‘ํ˜•