Skip to content

Commit

Permalink
First Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-Second committed May 6, 2022
1 parent 4f28042 commit 7064b83
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 0 deletions.
64 changes: 64 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
cmake_minimum_required(VERSION 3.14)

project(ImageViewer VERSION 0.1 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Quick QtWidgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Quick)

set(PROJECT_SOURCES
main.cpp
qml.qrc
images.qrc
cursor.hpp
image_util.hpp
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(ImageViewer
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET ImageViewer APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(ImageViewer SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(ImageViewer
${PROJECT_SOURCES}
)
endif()
endif()

target_compile_definitions(ImageViewer
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(ImageViewer
PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick)

set_target_properties(ImageViewer PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)

if(QT_VERSION_MAJOR EQUAL 6)
qt_import_qml_plugins(ImageViewer)
qt_finalize_executable(ImageViewer)
endif()
30 changes: 30 additions & 0 deletions SubWin.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import QtQuick 2.0
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

Window {
width: curImageHeight
height: curImageHeight
id: textwin
// flags: Qt.FramelessWindowHint
color: "#fad390"
ScrollView {
anchors.fill: parent
TextArea {
id: textarea
anchors.fill: parent
color: "black"
font.family: "Times New Roman"
text: rgb_str
padding: 0
textFormat: TextArea.RichText
focus: true
selectByMouse:true
selectByKeyboard: true
onTextChanged: {
textwin.height = textarea.contentHeight
textwin.width = textarea.contentWidth
}
}
}
}
30 changes: 30 additions & 0 deletions cursor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef CURSOR_HPP
#define CURSOR_HPP
#include <QDebug>
#include <QObject>
#include <QCursor>
#include <QPixmap>
#include <QQuickItem>

class Cursor: public QObject {
Q_OBJECT
public:
Cursor() {
cursor = QCursor(QPixmap(":/cursor.png").scaled(25,25, Qt::KeepAspectRatio));
};
~Cursor() = default;

Q_INVOKABLE void setHoveredCursor(QObject *obj) {
if(nullptr == obj)
return;
QQuickItem *itemObj = qobject_cast<QQuickItem*>(obj);
if(nullptr == itemObj)
return;
itemObj->setCursor(cursor);
}

private:
QCursor cursor;
};

#endif // CURSOR_HPP
Binary file added cursor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions image_util.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef IMAGE_UTIL_HPP
#define IMAGE_UTIL_HPP
#include <QImage>
#include <QStringList>
#include <QObject>
#include <QColor>
#include <QUrl>
#include <QRgb>
#include <QDebug>

class ImageUtil: public QObject{
Q_OBJECT
public:
ImageUtil() = default;
~ImageUtil() = default;

Q_INVOKABLE void setImage(const QUrl& url) {
this->cur_image = QImage(url.toLocalFile());
}

Q_INVOKABLE bool isReady() {
return !cur_image.isNull();
}

Q_INVOKABLE QString getImagePixelsOfArea(int x, int y, int width, int height) {

if(cur_image.isNull())
return "";

QStringList data;
auto start_x = x >= 0 ? x : 0;
auto start_y = y >= 0 ? y : 0;

auto end_x = (x + width) > cur_image.width() ? cur_image.width() : (x + width);
auto end_y = (y + height) > cur_image.height() ? cur_image.height() : (y + height);
// QStringList data;

for(int pixel_y = start_y; pixel_y < end_y; ++pixel_y) {
QString _data;
QString cur_value;
for(int pixel_x = start_x; pixel_x < end_x; ++pixel_x) {
auto color = cur_image.pixelColor(pixel_x, pixel_y);
QRgb rgb = color.rgb();
auto value = "#" + QString::number(rgb,16);
if(pixel_x == start_x) {
_data.append(QString("<font color='%1'>").arg(value));
cur_value = value;
} else if(value != cur_value) {
_data.append(QString("</font><font color='%1'>").arg(value));
cur_value = value;
}
_data.append(value + '\t');
}
_data = _data.trimmed() + "</font><br />";
data.append(_data);
}
// auto res = data.join('\n');
// qDebug() << res;
// exit(0);
return data.join("");
}
private:
QImage cur_image;
};

#endif // IMAGE_UTIL_HPP
7 changes: 7 additions & 0 deletions images.qrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/">
<file>magnifying-glass.png</file>
<file>startup-image.webp</file>
<file>cursor.png</file>
</qresource>
</RCC>
Binary file added magnifying-glass.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QIcon>
#include <QQmlContext>

#include "cursor.hpp"
#include "image_util.hpp"


int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);

app.setWindowIcon(QIcon(":/magnifying-glass.png"));

QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("cursor", new Cursor());
engine.rootContext()->setContextProperty("image_util", new ImageUtil());
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);

return app.exec();
}
89 changes: 89 additions & 0 deletions main.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import QtQuick 2.15
import QtQuick.Window 2.15
import Qt.labs.platform 1.1

Window {
property int curImageWidth: 885
property int curImageHeight: 505
height: curImageHeight
width: curImageWidth
visible: true
title: qsTr("ImageViewer")
id: mainwin

property string rgb_str: "null"

Component.onCompleted: {
subwin.show()
}

Image {
id: img
source: "qrc:/startup-image.webp"
fillMode: Image.PreserveAspectFit
anchors.fill: parent
onSourceSizeChanged: {
curImageWidth = sourceSize.width
curImageHeight = sourceSize.height
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton

onClicked: {
if (mouse.button === Qt.LeftButton) {
fileDialog.open()
} else {
if(!image_util.isReady())
return
var pixels_str = image_util.getImagePixelsOfArea(maskwin.x, maskwin.y, maskwin.width, maskwin.height)
rgb_str = pixels_str

// console.log(pixels_str[1])
}

}
HoverHandler {
onHoveredChanged: {
if(hovered) {
cursor.setHoveredCursor(parent)
} else {
cursorShape = Qt.ArrowCursor
}
}
}
onPositionChanged: {
maskwin.x = mouse.x - maskwin.width / 2 - 8
maskwin.y = mouse.y - maskwin.height / 2 + 10
}
}
}

SubWin {
id: subwin
visible: true
x: mainwin.x + mainwin.width
y: mainwin.y
}

FileDialog {
id: fileDialog
folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
fileMode: FileDialog.OpenFile
nameFilters: ["image files (*.png *.jpg *.tif *.jpeg *.webp)"]
onAccepted: {
// console.log(file)
img.source = file
image_util.setImage(file)
}
}

Rectangle {
id: maskwin
// anchors.centerIn: parent
width: 20
height: 20
color: "#1abc9c";
opacity: 0.3
}
}
6 changes: 6 additions & 0 deletions qml.qrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>SubWin.qml</file>
</qresource>
</RCC>
Binary file added startup-image.webp
Binary file not shown.

0 comments on commit 7064b83

Please sign in to comment.