Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions libimageviewer/unionimage/imgoperate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,40 @@
LibImgOperate::LibImgOperate(QObject *parent)
{
Q_UNUSED(parent);
qDebug() << "Initializing LibImgOperate";
}

LibImgOperate::~LibImgOperate()
{

qDebug() << "Destroying LibImgOperate";
}

void LibImgOperate::slotMakeImgThumbnail(QString thumbnailSavePath, QStringList paths, int makeCount, bool remake)
{
qDebug() << "Starting thumbnail generation for" << paths.size() << "images, makeCount:" << makeCount << "remake:" << remake;
QString path;
imageViewerSpace::ItemInfo itemInfo;
QImage tImg;
QImage tImg_1;
for (int i = 0; i < paths.size(); i++) {
//达到制作数量则停止
if (i == makeCount) {
qDebug() << "Reached makeCount limit, stopping thumbnail generation";
break;
}
path = paths.at(i);
qDebug() << "Processing image:" << path;
itemInfo.path = path;

//获取路径类型
itemInfo.pathType = getPathType(path);
qDebug() << "Path type:" << itemInfo.pathType;

//获取原图分辨率
QImageReader imagreader(path);
itemInfo.imgOriginalWidth = imagreader.size().width();
itemInfo.imgOriginalHeight = imagreader.size().height();
qDebug() << "Original image size:" << itemInfo.imgOriginalWidth << "x" << itemInfo.imgOriginalHeight;

//缩略图保存路径
QString savePath = thumbnailSavePath + path;
Expand All @@ -59,6 +65,7 @@ void LibImgOperate::slotMakeImgThumbnail(QString thumbnailSavePath, QStringList
QFileInfo file(savePath);
//缩略图已存在,执行下一个路径
if (file.exists() && !remake && itemInfo.imgOriginalWidth > 0 && itemInfo.imgOriginalHeight > 0) {
qDebug() << "Using existing thumbnail:" << savePath;
tImg = QImage(savePath);
itemInfo.image = tImg;
//获取图片类型
Expand All @@ -69,11 +76,12 @@ void LibImgOperate::slotMakeImgThumbnail(QString thumbnailSavePath, QStringList

QString errMsg;
if (!LibUnionImage_NameSpace::loadStaticImageFromFile(path, tImg, errMsg)) {
qDebug() << errMsg;
qWarning() << "Failed to load image:" << path << "Error:" << errMsg;
continue;
}
itemInfo.imgOriginalWidth = tImg.width();
itemInfo.imgOriginalHeight = tImg.height();
qDebug() << "Loaded image size:" << itemInfo.imgOriginalWidth << "x" << itemInfo.imgOriginalHeight;

if (0 != tImg.height() && 0 != tImg.width() && (tImg.height() / tImg.width()) < 10 && (tImg.width() / tImg.height()) < 10) {
bool cache_exist = false;
Expand All @@ -93,44 +101,65 @@ void LibImgOperate::slotMakeImgThumbnail(QString thumbnailSavePath, QStringList
tImg = tImg.scaledToHeight(200, Qt::FastTransformation);
}
}
qDebug() << "Scaled thumbnail size:" << tImg.width() << "x" << tImg.height();
}

//创建路径
pluginUtils::base::mkMutiDir(savePath.mid(0, savePath.lastIndexOf('/')));
QString dirPath = savePath.mid(0, savePath.lastIndexOf('/'));
qDebug() << "Creating directory for thumbnail:" << dirPath;
pluginUtils::base::mkMutiDir(dirPath);

if (tImg.save(savePath)) {
qDebug() << "Successfully saved thumbnail:" << savePath;
itemInfo.image = tImg;
} else {
qWarning() << "Failed to save thumbnail:" << savePath;
}

if (itemInfo.image.isNull()) {
qWarning() << "Generated thumbnail is null for:" << path;
itemInfo.imageType = imageViewerSpace::ImageTypeDamaged;
} else {
//获取图片类型
itemInfo.imageType = getImageType(path);
qDebug() << "Image type:" << itemInfo.imageType;
}
emit sigOneImgReady(path, itemInfo);
}
qDebug() << "Finished thumbnail generation";
}

imageViewerSpace::ImageType LibImgOperate::getImageType(const QString &imagepath)
{
qDebug() << "Getting image type for:" << imagepath;
return LibUnionImage_NameSpace::getImageType(imagepath);
}

imageViewerSpace::PathType LibImgOperate::getPathType(const QString &imagepath)
{
qDebug() << "Getting path type for:" << imagepath;
//判断文件路径来自于哪里
imageViewerSpace::PathType type = imageViewerSpace::PathType::PathTypeLOCAL;
if (imagepath.indexOf("smb-share:server=") != -1) {
type = imageViewerSpace::PathTypeSMB;
qDebug() << "Path type: SMB share";
} else if (imagepath.indexOf("mtp:host=") != -1) {
type = imageViewerSpace::PathTypeMTP;
qDebug() << "Path type: MTP device";
} else if (imagepath.indexOf("gphoto2:host=") != -1) {
type = imageViewerSpace::PathTypePTP;
qDebug() << "Path type: PTP device";
} else if (imagepath.indexOf("gphoto2:host=Apple") != -1) {
type = imageViewerSpace::PathTypeAPPLE;
qDebug() << "Path type: Apple device";
} else if (Libutils::image::isVaultFile(imagepath)) {
type = imageViewerSpace::PathTypeSAFEBOX;
qDebug() << "Path type: Safe box";
} else if (imagepath.contains(QDir::homePath() + "/.local/share/Trash")) {
type = imageViewerSpace::PathTypeRECYCLEBIN;
qDebug() << "Path type: Recycle bin";
} else {
qDebug() << "Path type: Local file";
}
//todo
return type;
}
37 changes: 32 additions & 5 deletions libimageviewer/unionimage/pluginbaseutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,14 @@ const QString DATETIME_FORMAT_EXIF = "yyyy:MM:dd HH:mm:ss";

bool checkMimeData(const QMimeData *mimeData)
{
qDebug() << "Checking mime data for drag and drop";
if (!mimeData->hasUrls()) {
qDebug() << "No URLs found in mime data";
return false;
}
QList<QUrl> urlList = mimeData->urls();
if (1 > urlList.size()) {
qDebug() << "Empty URL list in mime data";
return false;
}

Expand All @@ -189,12 +192,15 @@ bool checkMimeData(const QMimeData *mimeData)
if (path.isEmpty()) {
path = url.path();
}
qDebug() << "Processing URL path:" << path;
QFileInfo fileinfo(path);
if (fileinfo.isDir()) {
if (LibCommonService::instance()->getImgViewerType() == imageViewerSpace::ImgViewerType::ImgViewerTypeAlbum) { //相册模式的时候额外允许文件夹拖入
qDebug() << "Album mode: Directory drag allowed";
result = true;
break;
} else {
qDebug() << "Non-album mode: Directory drag not allowed";
continue;
}
} else {
Expand All @@ -203,18 +209,23 @@ bool checkMimeData(const QMimeData *mimeData)
QMimeType mt = db.mimeTypeForFile(info.filePath(), QMimeDatabase::MatchContent);
QMimeType mt1 = db.mimeTypeForFile(info.filePath(), QMimeDatabase::MatchExtension);
QString str = info.suffix().toLower();
qDebug() << "File suffix:" << str << "MIME type (content):" << mt.name() << "MIME type (extension):" << mt1.name();

if (str.isEmpty()) {
if (mt.name().startsWith("image/") || mt.name().startsWith("video/x-mng")) {
if (supportedImageFormats().contains(str, Qt::CaseInsensitive)) {
qDebug() << "Empty suffix but supported format found";
result = true;
break;
} else if (str.isEmpty()) {
qDebug() << "Empty suffix but valid image MIME type";
result = true;
break;
}
}
} else {
if (mt1.name().startsWith("image/") || mt1.name().startsWith("video/x-mng")) {
qDebug() << "Valid image format with extension";
result = true;
break;
}
Expand All @@ -223,6 +234,7 @@ bool checkMimeData(const QMimeData *mimeData)
}
}

qDebug() << "Mime data check result:" << result;
return result;
}

Expand All @@ -248,45 +260,56 @@ bool checkMimeData(const QMimeData *mimeData)

QString mkMutiDir(const QString &path) //创建多级目录
{
qDebug() << "Creating directory structure for:" << path;
QDir dir(path);
if (dir.exists(path)) {
qDebug() << "Directory already exists:" << path;
return path;
}
QString parentDir = mkMutiDir(path.mid(0, path.lastIndexOf('/')));
QString dirname = path.mid(path.lastIndexOf('/') + 1);
QDir parentPath(parentDir);
if (!dirname.isEmpty())
if (!dirname.isEmpty()) {
qDebug() << "Creating subdirectory:" << dirname << "in" << parentDir;
parentPath.mkpath(dirname);
}
return parentDir + "/" + dirname;
}

bool imageSupportRead(const QString &path)
{
qDebug() << "Checking if image format is supported for:" << path;
const QString suffix = QFileInfo(path).suffix();
// take them here for good.
QStringList errorList;
errorList << "X3F";
if (errorList.indexOf(suffix.toUpper()) != -1) {
qWarning() << "Unsupported format:" << suffix;
return false;
}
//return QImageReader::supportedImageFormats().contains(suffix.toUtf8());
return LibUnionImage_NameSpace::unionImageSupportFormat().contains(suffix.toUpper());
bool supported = LibUnionImage_NameSpace::unionImageSupportFormat().contains(suffix.toUpper());
qDebug() << "Format support check result:" << supported;
return supported;
}

const QFileInfoList getImagesInfo(const QString &dir, bool recursive)
{
qDebug() << "Getting image information from directory:" << dir << "recursive:" << recursive;
QFileInfoList infos;

if (! recursive) {
qDebug() << "Non-recursive directory scan";
auto nsl = QDir(dir).entryInfoList(QDir::Files);
for (QFileInfo info : nsl) {
if (imageSupportRead(info.absoluteFilePath())) {
infos << info;
}
}
qDebug() << "Found" << infos.size() << "images in directory";
return infos;
}

qDebug() << "Recursive directory scan";
QDirIterator dirIterator(dir,
QDir::Files,
QDirIterator::Subdirectories);
Expand All @@ -297,12 +320,16 @@ const QFileInfoList getImagesInfo(const QString &dir, bool recursive)
}
}

qDebug() << "Found" << infos.size() << "images in directory and subdirectories";
return infos;
}
//

QStringList supportedImageFormats()
{
return LibUnionImage_NameSpace::unionImageSupportFormat();
qDebug() << "Getting list of supported image formats";
QStringList formats = LibUnionImage_NameSpace::unionImageSupportFormat();
qDebug() << "Supported formats:" << formats;
return formats;
}

} // namespace base
Expand Down
23 changes: 21 additions & 2 deletions libimageviewer/unionimage/snifferimageformat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,95 +11,114 @@
// https://en.wikipedia.org/wiki/Image_file_formats
QString DetectImageFormat(const QString &filepath)
{
qDebug() << "Starting image format detection for:" << filepath;
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "DetectImageFormat() failed to open file:" << filepath;
qWarning() << "Failed to open file for format detection:" << filepath;
return "";
}

const QByteArray data = file.read(1024);
qDebug() << "Read" << data.size() << "bytes for format detection";

// Check bmp file.
if (data.startsWith("BM")) {
qDebug() << "Detected BMP format";
return "bmp";
}

// Check dds file.
if (data.startsWith("DDS")) {
qDebug() << "Detected DDS format";
return "dds";
}

// Check gif file.
if (data.startsWith("GIF8")) {
qDebug() << "Detected GIF format";
return "gif";
}

// Check Max OS icons file.
if (data.startsWith("icns")) {
qDebug() << "Detected ICNS format";
return "icns";
}

// Check jpeg file.
if (data.startsWith("\xff\xd8")) {
qDebug() << "Detected JPEG format";
return "jpg";
}

// Check mng file.
if (data.startsWith("\x8a\x4d\x4e\x47\x0d\x0a\x1a\x0a")) {
qDebug() << "Detected MNG format";
return "mng";
}

// Check net pbm file (BitMap).
if (data.startsWith("P1") || data.startsWith("P4")) {
qDebug() << "Detected PBM format";
return "pbm";
}

// Check pgm file (GrayMap).
if (data.startsWith("P2") || data.startsWith("P5")) {
qDebug() << "Detected PGM format";
return "pgm";
}

// Check ppm file (PixMap).
if (data.startsWith("P3") || data.startsWith("P6")) {
qDebug() << "Detected PPM format";
return "ppm";
}

// Check png file.
if (data.startsWith("\x89PNG\x0d\x0a\x1a\x0a")) {
qDebug() << "Detected PNG format";
return "png";
}

// Check svg file.
if (data.indexOf("<svg") > -1) {
qDebug() << "Detected SVG format";
return "svg";
}

// TODO(xushaohua): tga file is not supported yet.
qDebug() << "TGA format detection not implemented yet";

// Check tiff file.
if (data.startsWith("MM\x00\x2a") || data.startsWith("II\x2a\x00")) {
// big-endian, little-endian.
qDebug() << "Detected TIFF format";
return "tiff";
}

// TODO(xushaohua): Support wbmp file.
qDebug() << "WBMP format detection not implemented yet";

// Check webp file.
if (data.startsWith("RIFFr\x00\x00\x00WEBPVP")) {
qDebug() << "Detected WebP format";
return "webp";
}

// Check xbm file.
if (data.indexOf("#define max_width ") > -1 &&
data.indexOf("#define max_height ") > -1) {
qDebug() << "Detected XBM format";
return "xbm";
}

// Check xpm file.
if (data.startsWith("/* XPM */")) {
qDebug() << "Detected XPM format";
return "xpm";
}


qDebug() << "No supported image format detected";
return "";
}
Loading
Loading