{"id":15625861,"url":"https://github.com/xinntao/handyview","last_synced_at":"2025-10-08T19:11:14.742Z","repository":{"id":38302280,"uuid":"131566179","full_name":"xinntao/HandyView","owner":"xinntao","description":"Handy image viewer based on PyQt5. Convenient for viewing and comparing :-)","archived":false,"fork":false,"pushed_at":"2024-09-03T21:35:48.000Z","size":8259,"stargazers_count":641,"open_issues_count":8,"forks_count":66,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-09-25T14:54:13.639Z","etag":null,"topics":["handyview","handyviewer","image-viewer","pyqt5","zoom"],"latest_commit_sha":null,"homepage":"http://xinntao.github.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xinntao.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-30T07:11:49.000Z","updated_at":"2025-09-24T07:04:13.000Z","dependencies_parsed_at":"2024-10-22T22:53:55.397Z","dependency_job_id":null,"html_url":"https://github.com/xinntao/HandyView","commit_stats":{"total_commits":76,"total_committers":4,"mean_commits":19.0,"dds":0.09210526315789469,"last_synced_commit":"ca66c7b67b75f401fff31cc0d8e4523ea8cd62ba"},"previous_names":["xinntao/handyviewer"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/xinntao/HandyView","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinntao%2FHandyView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinntao%2FHandyView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinntao%2FHandyView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinntao%2FHandyView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xinntao","download_url":"https://codeload.github.com/xinntao/HandyView/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xinntao%2FHandyView/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000701,"owners_count":26082805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["handyview","handyviewer","image-viewer","pyqt5","zoom"],"created_at":"2024-10-03T10:06:56.789Z","updated_at":"2025-10-08T19:11:14.725Z","avatar_url":"https://github.com/xinntao.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"icon_text.png\" height=100\u003e\n\u003c/p\u003e\n\n## \u003cdiv align=\"center\"\u003e\u003cb\u003e\u003ca href=\"README.md\"\u003eEnglish\u003c/a\u003e | \u003ca href=\"README_CN.md\"\u003e简体中文\u003c/a\u003e\u003c/b\u003e\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![download](https://img.shields.io/github/downloads/xinntao/HandyView/total)](https://github.com/xinntao/HandyView/releases)\n![visitors](https://visitor-badge.glitch.me/badge?page_id=xinntao/HandyView)\n[![PyPI](https://img.shields.io/pypi/v/handyview)](https://pypi.org/project/handyview/)\n[![license](https://img.shields.io/github/license/xinntao/HandyView)](https://github.com/xinntao/HandyView/blob/master/LICENSE)\n[![python lint](https://github.com/xinntao/HandyView/actions/workflows/pylint.yml/badge.svg)](https://github.com/xinntao/HandyView/blob/master/.github/workflows/pylint.yml)\n[![Publish-pip](https://github.com/xinntao/HandyView/actions/workflows/publish-pip.yml/badge.svg)](https://github.com/xinntao/HandyView/blob/master/.github/workflows/publish-pip.yml)\n[![Release](https://github.com/xinntao/HandyView/actions/workflows/release.yml/badge.svg)](https://github.com/xinntao/HandyView/blob/master/.github/workflows/release.yml)\n\n \u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n  🔻[**Executable files**](https://github.com/xinntao/HandyView/releases) **|** 🔧[**Installation**](#-Installation)  **|** 📕[**使用说明**](docs)\n \u003c/div\u003e\n\nHandyView is a **handy image viewer** for convenient viewing and comparing. It is developed with PyQt5.\n\n---\n\n```Handy``` *Series*: \u0026emsp;\u0026emsp;\n\u003cimg src=\"https://github.com/xinntao/HandyView/blob/master/icon.png\" alt=\"HandyView Icon\" width=\"36\" height=\"36\"\u003e [HandyView](https://github.com/xinntao/HandyView) \u0026emsp; \u003cimg src=\"https://github.com/xinntao/HandyFigure/blob/master/icon.png\" alt=\"HandyFigure Icon\" width=\"36\" height=\"36\"\u003e [HandyFigure](https://github.com/xinntao/HandyFigure) \u0026emsp; \u003cimg src=\"https://github.com/xinntao/HandyCrawler/blob/master/icon.png\" alt=\"HandyCrawler Icon\" width=\"36\" height=\"36\"\u003e [HandyCrawler](https://github.com/xinntao/HandyCrawler)\n\u0026emsp; \u003cimg src=\"https://github.com/xinntao/HandyWriting/blob/master/icon.png\" alt=\"HandyWriting Icon\" width=\"36\" height=\"36\"\u003e [HandyWriting](https://github.com/xinntao/HandyWriting)\n\n\n## 🔧 Installation\n\n### \u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/8/8d/Windows_darkblue_2012.svg\" alt=\"Windows\" height=\"28\"\u003e\n\n1. Download the pre-compiled executable zip file from the [release page](https://github.com/xinntao/HandyView/releases).\n2. Unzip the file\n3. Set HandyView as the default image viewer, so that you can **double-click the image to open** HandyView.\n\n### \u003cimg src=\"https://user-images.githubusercontent.com/11482921/171234862-5a54e430-7c07-4976-9ac8-ce8dbf520a17.png\" alt=\"MacOS\" height=\"24\"\u003e\n\n1. Download the handyviewer.dmg from the [release page](https://github.com/xinntao/HandyView/releases) and install.\n2. If you fail to install the app, you may first need to [disable gatekeeper](https://disable-gatekeeper.github.io/) first. You should be aware of the risk of [disabling gatekeeper](https://disable-gatekeeper.github.io/).\n3. Set HandyView as the default image viewer (use `cmd+i`), so that you can **double-click the image to open** HandyView.\n\n### \u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/3/3a/Logo-ubuntu_no%28r%29-black_orange-hex.svg\" alt=\"Ubuntu\" height=\"24\"\u003e\n\nI used the early version of HandyView on Ubuntu. The current version is not tested on Ubuntu and may be out-of-date.\n\n1. Clone this repo `git clone https://github.com/xinntao/HandyView.git`\n1. How to double click to open an image\n    1. Modify the HandyView.desktop file - *Exec \u0026 Icon*\n    1. Copy the .desktop file to `/usr/share/applications`\n1. How to change the default image viewer\n    1. Right click an image\n    1. Go to `Properties` -\u003e `Open With`\n    1. Choose *HandyView*\n\n### \u003cimg src=\"https://user-images.githubusercontent.com/11482921/171239036-858e2c00-835f-4278-afb4-5b8ac3fe2b65.png\" alt=\"Ubuntu\" height=\"38\"\u003e\n\nFor python user, you can also launch HandyView from the command line:\n\n1. Clone repo and install dependent packages\n\n    ```bash\n    git clone https://github.com/xinntao/HandyView.git\n    cd HandyView\n    pip install -r requirements.txt\n    ```\n\n2. Run\n\n    ```bash\n    python -m handyview.handyviewer [image_path]\n    ```\n\n## :sparkles: Features\n\n- Switch among images **with fixed zoom ration**, which is useful when comparing image details. (Unfortunately, I cannot find such a image viewer and this is the initial motivation to develop HandyView).\n- Various comparison modes.\n- Show basic image information, *e.g.*, image path, shape, size, color type, zoom ration, etc.\n- Show the position and color in the current mouse cursor.\n- Draw rectangles on images and show the start and end position.\n\n## :eyes: Screenshot\n\n- Current screenshot\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/screenshot.png\" height=\"400\"\u003e\n\u003c/p\u003e\n\n- Switch among images with **fixed zoom ratio**\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/hv_switch.gif\" height=\"400\"\u003e\n\u003c/p\u003e\n\n- Compare images in two-column or three-column modes\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/hv_cmp.gif\" height=\"400\"\u003e\n\u003c/p\u003e\n\n- Show the position and color of the current mouse cursor\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/hv_mousemove.gif\" height=\"400\"\u003e\n\u003c/p\u003e\n\n- Draw rectangles and show the start and end positions\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/hv_rect.gif\" height=\"400\"\u003e\n\u003c/p\u003e\n\n## Compile to executable program\n\nFor Windows and MacOS users, you can find the instructions of compiling the executable program from [how-to-build](how_to_build.md).\n\n## :book: Document (On the way)\n\nThe basic operation (such as shortcut keys) could be found in the *Help* button in the toolbar.\n\n## :hourglass_flowing_sand: TODO list\n\n- [ ] preview mode\n- [ ] show zoom info for each folder (store in database)\n- [ ] drag together in the multi-view comparison mode\n\n### Editing operation\n\n- [ ] Simple image edit: crop, resize, color conversion, etc\n- [ ] Draw rectangular and enlarged the area\n- [ ] Make GIF easily\n\n## :books: References\n\n- [Qt5 doc](https://doc.qt.io/qt-5/)\n- [PyQt5 doc](https://doc.qt.io/qtforpython/api.html)\n- [Qt Key](https://doc.qt.io/archives/qtjambi-4.5.2_01/com/trolltech/qt/core/Qt.Key.html)\n\n## :scroll: License and Acknowledgement\n\nThis project is released under the [MIT license](./LICENSE).\n\n### Icons\n\nI have used the icons from [flaticon](www.flaticon.com). The following are the source links.\n\n| Icon | Link | Icon | Link | Icon |Link|\n| :--- | :---:        |     :---      | :---: | :---        |     :---:      |\n| \u003cimg src=\"icons/open.png\" height=\"32\" alt=\"Open\"\u003e  | [Open](https://www.flaticon.com/free-icon/open_3143203?term=file%20open\u0026page=1\u0026position=1) | \u003cimg src=\"icons/history.png\" height=\"32\" alt=\"History\"\u003e|[History](https://www.flaticon.com/free-icon/timer_2921268) | \u003cimg src=\"icons/refresh.png\" height=\"32\" alt=\"Refresh\"\u003e |[Refresh](https://www.flaticon.com/free-icon/reuse_3299869?term=refresh\u0026page=1\u0026position=16) |\n| \u003cimg src=\"icons/index.png\" height=\"32\" alt=\"Index\"\u003e  | [Index](https://www.flaticon.com/free-icon/index_2807595?term=index\u0026page=1\u0026position=8) | \u003cimg src=\"icons/include.png\" height=\"32\" alt=\"Include\"\u003e |[Include](https://www.flaticon.com/free-icon/add_2921226) | \u003cimg src=\"icons/exclude.png\" height=\"32\" alt=\"Exclude\"\u003e|[Exclude](https://www.flaticon.com/free-icon/remove_2921203) |\n| \u003cimg src=\"icons/compare.png\" height=\"32\" alt=\"Compare\"\u003e  | [Compare](https://www.flaticon.com/free-icon/file_748614?term=compare\u0026page=1\u0026position=17) | \u003cimg src=\"icons/clear_comparison.png\" height=\"32\" alt=\"Clear comparison\"\u003e |[Clear comparison](https://www.flaticon.com/free-icon/eraser_3277337?term=clear\u0026page=1\u0026position=5) |\u003cimg src=\"icons/instructions.png\" height=\"32\" alt=\"Help\"\u003e  |[Help](https://www.flaticon.com/free-icon/information-point_4231321?term=help\u0026page=1\u0026position=87\u0026page=1\u0026position=87)|\n| \u003cimg src=\"icons/main_canvas.png\" height=\"32\" alt=\"Main canvas\"\u003e  | [Main canvas](https://www.flaticon.com/free-icon/image_3603103) | \u003cimg src=\"icons/compare_canvas.png\" height=\"32\" alt=\"Compare canvas\"\u003e |[Compare canvas](https://www.flaticon.com/free-icon/portraits_3603402) |  \u003cimg src=\"icons/preview_canvas.png\" height=\"32\" alt=\"Preview canvas\"\u003e  |[Preview canvas](https://www.flaticon.com/free-icon/pieces_3603403)|\n| \u003cimg src=\"icons/fingerprint.png\" height=\"32\" alt=\"Fingerprint\"\u003e  | [Fingerprint](https://www.flaticon.com/free-icon/fingerprint_2313448?term=fingerprint\u0026page=1\u0026position=7) | \u003cimg src=\"icons/auto_zoom.png\" height=\"32\" alt=\"auto zoom\"\u003e | [Auto Zoom](https://www.flaticon.com/premium-icon/target_4723850?term=target%20lens\u0026page=1\u0026position=5\u0026page=1\u0026position=5\u0026related_id=4723850\u0026origin=search)  |  | |\n| \u003cimg src=\"icons/image.png\" height=\"32\" alt=\"auto image\"\u003e | [Image](https://www.flaticon.com/free-icon/image_1829589) | \u003cimg src=\"icons/crop.png\" height=\"32\" alt=\"crop\"\u003e  | [Crop](https://www.flaticon.com/free-icon/crop_3342178)   | \u003cimg src=\"icons/video.png\" height=\"32\" alt=\"video\"\u003e | [Video](https://www.flaticon.com/free-icon/facebook_4406124) |\n\n(pip install pyqt5 -i \u003chttp://mirrors.xxx.com/pypi/simple/\u003e --trusted-host mirrors.xxx.com)\n\n## :e-mail: Contact\n\nIf you have any question, please open an issue or email `xintao.wang@outlook.com`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxinntao%2Fhandyview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxinntao%2Fhandyview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxinntao%2Fhandyview/lists"}