Created Image class to encapsulate some transforms with QImage

This commit is contained in:
Olivier Prat 2019-03-29 12:23:44 +01:00
parent c480f36dd4
commit 7455ddb7ba
17 changed files with 1762 additions and 1591 deletions

View file

@ -33,7 +33,7 @@
#include <NodeType.h>
#include <SharedUtil.h>
#include <PathUtils.h>
#include <image/Image.h>
#include <image/TextureProcessing.h>
#include "AssetServerLogging.h"
#include "BakeAssetTask.h"

View file

@ -16,7 +16,7 @@
#include <QtCore/QFile>
#include <QtNetwork/QNetworkReply>
#include <image/Image.h>
#include <image/TextureProcessing.h>
#include <ktx/KTX.h>
#include <NetworkAccessManager.h>
#include <SharedUtil.h>

View file

@ -18,7 +18,7 @@
#include <QDir>
#include <QImageReader>
#include <image/Image.h>
#include <image/TextureProcessing.h>
#include "Baker.h"

View file

@ -15,7 +15,7 @@
#include <QtCore/QFileInfo>
#include <QHash>
#include <image/Image.h>
#include <image/TextureProcessing.h>
class TextureFileNamer {
public:

View file

@ -15,7 +15,7 @@
#include "GraphicsScriptingUtil.h"
#include "ScriptableMesh.h"
#include "graphics/Material.h"
#include "image/Image.h"
#include "image/TextureProcessing.h"
// #define SCRIPTABLE_MESH_DEBUG 1

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,10 @@
#pragma once
//
// Image.h
// image/src/image
// image/src/Image
//
// Created by Clement Brisset on 4/5/2017.
// Copyright 2017 High Fidelity, Inc.
// Created by Olivier Prat on 29/3/2019.
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -12,85 +13,85 @@
#ifndef hifi_image_Image_h
#define hifi_image_Image_h
#include <QVariant>
#include <QImage>
#include <gpu/Texture.h>
#include "ColorChannel.h"
class QByteArray;
#include <glm/fwd.hpp>
#include <glm/vec2.hpp>
#include <GLMHelpers.h>
namespace image {
extern const QImage::Format QIMAGE_HDRFORMAT;
class Image {
public:
std::function<gpu::uint32(const glm::vec3&)> getHDRPackingFunction();
std::function<glm::vec3(gpu::uint32)> getHDRUnpackingFunction();
enum Format {
Format_Invalid = QImage::Format_Invalid,
Format_Mono = QImage::Format_Mono,
Format_MonoLSB = QImage::Format_MonoLSB,
Format_Indexed8 = QImage::Format_Indexed8,
Format_RGB32 = QImage::Format_RGB32,
Format_ARGB32 = QImage::Format_ARGB32,
Format_ARGB32_Premultiplied = QImage::Format_ARGB32_Premultiplied,
Format_RGB16 = QImage::Format_RGB16,
Format_ARGB8565_Premultiplied = QImage::Format_ARGB8565_Premultiplied,
Format_RGB666 = QImage::Format_RGB666,
Format_ARGB6666_Premultiplied = QImage::Format_ARGB6666_Premultiplied,
Format_RGB555 = QImage::Format_RGB555,
Format_ARGB8555_Premultiplied = QImage::Format_ARGB8555_Premultiplied,
Format_RGB888 = QImage::Format_RGB888,
Format_RGB444 = QImage::Format_RGB444,
Format_ARGB4444_Premultiplied = QImage::Format_ARGB4444_Premultiplied,
Format_RGBX8888 = QImage::Format_RGBX8888,
Format_RGBA8888 = QImage::Format_RGBA8888,
Format_RGBA8888_Premultiplied = QImage::Format_RGBA8888_Premultiplied,
Format_Grayscale8 = QImage::Format_Grayscale8,
Format_R11G11B10F = QImage::Format_RGB30,
Format_PACKED_FLOAT = Format_R11G11B10F
};
namespace TextureUsage {
using AspectRatioMode = Qt::AspectRatioMode;
using TransformationMode = Qt::TransformationMode;
enum Type {
DEFAULT_TEXTURE,
STRICT_TEXTURE,
ALBEDO_TEXTURE,
NORMAL_TEXTURE,
BUMP_TEXTURE,
SPECULAR_TEXTURE,
METALLIC_TEXTURE = SPECULAR_TEXTURE, // for now spec and metallic texture are the same, converted to grey
ROUGHNESS_TEXTURE,
GLOSS_TEXTURE,
EMISSIVE_TEXTURE,
CUBE_TEXTURE,
OCCLUSION_TEXTURE,
SCATTERING_TEXTURE = OCCLUSION_TEXTURE,
LIGHTMAP_TEXTURE,
UNUSED_TEXTURE
};
Image() {}
Image(int width, int height, Format format) : _data(width, height, (QImage::Format)format) {}
Image(const QImage& data) : _data(data) {}
void operator=(const QImage& image) {
_data = image;
}
using TextureLoader = std::function<gpu::TexturePointer(QImage&&, const std::string&, bool, gpu::BackendTarget, const std::atomic<bool>&)>;
TextureLoader getTextureLoaderForType(Type type, const QVariantMap& options = QVariantMap());
bool isNull() const { return _data.isNull(); }
gpu::TexturePointer create2DTextureFromImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createStrict2DTextureFromImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createAlbedoTextureFromImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createEmissiveTextureFromImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createNormalTextureFromNormalImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createNormalTextureFromBumpImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createRoughnessTextureFromImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createRoughnessTextureFromGlossImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createMetallicTextureFromImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createCubeTextureFromImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createCubeTextureFromImageWithoutIrradiance(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createLightmapTextureFromImage(QImage&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer process2DTextureColorFromImage(QImage&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool isStrict, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer process2DTextureNormalMapFromImage(QImage&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool isBumpMap, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer process2DTextureGrayscaleFromImage(QImage&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool isInvertedPixels, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer processCubeTextureColorFromImage(QImage&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool generateIrradiance, const std::atomic<bool>& abortProcessing);
Format getFormat() const { return (Format)_data.format(); }
bool hasAlphaChannel() const { return _data.hasAlphaChannel(); }
} // namespace TextureUsage
glm::uint32 getWidth() const { return (glm::uint32)_data.width(); }
glm::uint32 getHeight() const { return (glm::uint32)_data.height(); }
glm::uvec2 getSize() const { return toGlm(_data.size()); }
size_t getByteCount() const { return _data.byteCount(); }
const QStringList getSupportedFormats();
QRgb getPixel(int x, int y) const { return _data.pixel(x, y); }
void setPixel(int x, int y, QRgb value) {
_data.setPixel(x, y, value);
}
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& url, ColorChannel sourceChannel,
int maxNumPixels, TextureUsage::Type textureType,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing = false);
glm::uint8* editScanLine(int y) { return _data.scanLine(y); }
const glm::uint8* getScanLine(int y) const { return _data.scanLine(y); }
const glm::uint8* getBits() const { return _data.constBits(); }
Image getScaled(glm::uvec2 newSize, AspectRatioMode ratioMode, TransformationMode transformationMode = Qt::SmoothTransformation) const;
Image getConvertedToFormat(Format newFormat) const;
Image getSubImage(QRect rect) const;
Image getMirrored(bool horizontal, bool vertical) const;
// Inplace transformations
void invertPixels();
private:
QImage _data;
};
} // namespace image

View file

@ -11,7 +11,7 @@
#include "OpenEXRReader.h"
#include "Image.h"
#include "TextureProcessing.h"
#include "ImageLogging.h"
#include <QIODevice>
@ -58,7 +58,7 @@ private:
#endif
QImage image::readOpenEXR(QIODevice& content, const std::string& filename) {
image::Image image::readOpenEXR(QIODevice& content, const std::string& filename) {
#if !defined(Q_OS_ANDROID)
QIODeviceImfStream device(content, filename);
@ -74,12 +74,12 @@ QImage image::readOpenEXR(QIODevice& content, const std::string& filename) {
file.setFrameBuffer(&pixels[0][0] - viewport.min.x - viewport.min.y * width, 1, width);
file.readPixels(viewport.min.y, viewport.max.y);
QImage image{ width, height, QIMAGE_HDRFORMAT };
Image image{ width, height, Image::Format_PACKED_FLOAT };
auto packHDRPixel = getHDRPackingFunction();
for (int y = 0; y < height; y++) {
const auto srcScanline = pixels[y];
gpu::uint32* dstScanline = (gpu::uint32*) image.scanLine(y);
gpu::uint32* dstScanline = (gpu::uint32*) image.editScanLine(y);
for (int x = 0; x < width; x++) {
const auto& srcPixel = srcScanline[x];

View file

@ -12,12 +12,12 @@
#ifndef hifi_image_OpenEXRReader_h
#define hifi_image_OpenEXRReader_h
#include <QImage>
#include "Image.h"
namespace image {
// TODO Move this into a plugin that QImageReader can use
QImage readOpenEXR(QIODevice& contents, const std::string& filename);
Image readOpenEXR(QIODevice& contents, const std::string& filename);
}

View file

@ -16,7 +16,7 @@
#include <QIODevice>
#include <QDebug>
QImage image::readTGA(QIODevice& content) {
image::Image image::readTGA(QIODevice& content) {
enum class TGAImageType : uint8_t {
NoImageData = 0,
UncompressedColorMapped = 1,

View file

@ -12,12 +12,11 @@
#ifndef hifi_image_TGAReader_h
#define hifi_image_TGAReader_h
#include <QImage>
#include "Image.h"
namespace image {
// TODO Move this into a plugin that QImageReader can use
QImage readTGA(QIODevice& contents);
Image readTGA(QIODevice& contents);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,92 @@
//
// TextureProcessing.h
// image/src/TextureProcessing
//
// Created by Clement Brisset on 4/5/2017.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_image_TextureProcessing_h
#define hifi_image_TextureProcessing_h
#include <QVariant>
#include <gpu/Texture.h>
#include "Image.h"
namespace image {
std::function<gpu::uint32(const glm::vec3&)> getHDRPackingFunction();
std::function<glm::vec3(gpu::uint32)> getHDRUnpackingFunction();
namespace TextureUsage {
enum Type {
DEFAULT_TEXTURE,
STRICT_TEXTURE,
ALBEDO_TEXTURE,
NORMAL_TEXTURE,
BUMP_TEXTURE,
SPECULAR_TEXTURE,
METALLIC_TEXTURE = SPECULAR_TEXTURE, // for now spec and metallic texture are the same, converted to grey
ROUGHNESS_TEXTURE,
GLOSS_TEXTURE,
EMISSIVE_TEXTURE,
CUBE_TEXTURE,
OCCLUSION_TEXTURE,
SCATTERING_TEXTURE = OCCLUSION_TEXTURE,
LIGHTMAP_TEXTURE,
UNUSED_TEXTURE
};
using TextureLoader = std::function<gpu::TexturePointer(Image&&, const std::string&, bool, gpu::BackendTarget, const std::atomic<bool>&)>;
TextureLoader getTextureLoaderForType(Type type, const QVariantMap& options = QVariantMap());
gpu::TexturePointer create2DTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createStrict2DTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createAlbedoTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createEmissiveTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createNormalTextureFromNormalImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createNormalTextureFromBumpImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createRoughnessTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createRoughnessTextureFromGlossImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createMetallicTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createCubeTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createCubeTextureFromImageWithoutIrradiance(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer createLightmapTextureFromImage(Image&& image, const std::string& srcImageName,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer process2DTextureColorFromImage(Image&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool isStrict, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer process2DTextureNormalMapFromImage(Image&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool isBumpMap, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer process2DTextureGrayscaleFromImage(Image&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool isInvertedPixels, const std::atomic<bool>& abortProcessing);
gpu::TexturePointer processCubeTextureColorFromImage(Image&& srcImage, const std::string& srcImageName, bool compress,
gpu::BackendTarget target, bool generateIrradiance, const std::atomic<bool>& abortProcessing);
} // namespace TextureUsage
const QStringList getSupportedFormats();
gpu::TexturePointer processImage(std::shared_ptr<QIODevice> content, const std::string& url, ColorChannel sourceChannel,
int maxNumPixels, TextureUsage::Type textureType,
bool compress, gpu::BackendTarget target, const std::atomic<bool>& abortProcessing = false);
} // namespace image
#endif // hifi_image_TextureProcessing_h

View file

@ -34,7 +34,7 @@
#include <gl/GLHelpers.h>
#include <gpu/Batch.h>
#include <image/Image.h>
#include <image/TextureProcessing.h>
#include <NumericalConstants.h>
#include <shared/NsightHelpers.h>

View file

@ -23,7 +23,7 @@
#include <ResourceCache.h>
#include <graphics/TextureMap.h>
#include <image/ColorChannel.h>
#include <image/Image.h>
#include <image/TextureProcessing.h>
#include <ktx/KTX.h>
#include <TextureMeta.h>

View file

@ -14,7 +14,7 @@
#include <QtCore/QDebug>
#include <QtCore/QThread>
#include <image/Image.h>
#include <image/TextureProcessing.h>
#include <DependencyManager.h>
#include <StatTracker.h>

View file

@ -14,7 +14,7 @@
#include <QtCore/QCommandLineParser>
#include <QtCore/QUrl>
#include <image/Image.h>
#include <image/TextureProcessing.h>
#include <TextureBaker.h>
#include "BakerCLI.h"