start histogram, fix image orientation
This commit is contained in:
parent
bb4f324016
commit
301d32474b
94
lib/histogram.h
Normal file
94
lib/histogram.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
#include "./imgui.h"
|
||||||
|
#include "./imgui_internal.h"
|
||||||
|
|
||||||
|
class Histogram {
|
||||||
|
|
||||||
|
public:
|
||||||
|
unsigned int **counts = nullptr;
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
int channels = 0;
|
||||||
|
|
||||||
|
Histogram();
|
||||||
|
|
||||||
|
void Load() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void Draw() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void histogram(const int width, const int height, const int channels, const unsigned char* const bits) {
|
||||||
|
unsigned int count[4][256] = {0};
|
||||||
|
|
||||||
|
const unsigned char* ptrCols = bits;
|
||||||
|
|
||||||
|
ImGui::InvisibleButton("histogram", ImVec2(512, 256));
|
||||||
|
for (int l = 0; l < height * width; l++)
|
||||||
|
{
|
||||||
|
count[0][*ptrCols++]++;
|
||||||
|
count[1][*ptrCols++]++;
|
||||||
|
count[2][*ptrCols++]++;
|
||||||
|
count[3][*ptrCols++]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int maxv = count[0][0];
|
||||||
|
unsigned int* pCount = &count[0][0];
|
||||||
|
for (int i = 0; i < 3 * 256; i++, pCount++)
|
||||||
|
{
|
||||||
|
maxv = (maxv > *pCount) ? maxv : *pCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
||||||
|
const ImVec2 rmin = ImGui::GetItemRectMin();
|
||||||
|
const ImVec2 rmax = ImGui::GetItemRectMax();
|
||||||
|
const ImVec2 size = ImGui::GetItemRectSize();
|
||||||
|
const float hFactor = size.y / float(maxv);
|
||||||
|
|
||||||
|
for (int i = 0; i <= 10; i++)
|
||||||
|
{
|
||||||
|
float ax = rmin.x + (size.x / 10.f) * float(i);
|
||||||
|
float ay = rmin.y + (size.y / 10.f) * float(i);
|
||||||
|
drawList->AddLine(ImVec2(rmin.x, ay), ImVec2(rmax.x, ay), 0x80808080);
|
||||||
|
drawList->AddLine(ImVec2(ax, rmin.y), ImVec2(ax, rmax.y), 0x80808080);
|
||||||
|
}
|
||||||
|
|
||||||
|
const float barWidth = (size.x / 256.f);
|
||||||
|
for (int j = 0; j < 256; j++)
|
||||||
|
{
|
||||||
|
// pixel count << 2 + color index(on 2 bits)
|
||||||
|
uint32_t cols[3] = {(count[0][j] << 2), (count[1][j] << 2) + 1, (count[2][j] << 2) + 2};
|
||||||
|
if (cols[0] > cols[1])
|
||||||
|
ImSwap(cols[0], cols[1]);
|
||||||
|
if (cols[1] > cols[2])
|
||||||
|
ImSwap(cols[1], cols[2]);
|
||||||
|
if (cols[0] > cols[1])
|
||||||
|
ImSwap(cols[0], cols[1]);
|
||||||
|
float heights[3];
|
||||||
|
uint32_t colors[3];
|
||||||
|
uint32_t currentColor = 0xFFFFFFFF;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
heights[i] = rmax.y - (cols[i] >> 2) * hFactor;
|
||||||
|
colors[i] = currentColor;
|
||||||
|
currentColor -= 0xFF << ((cols[i] & 3) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
float currentHeight = rmax.y;
|
||||||
|
const float left = rmin.x + barWidth * float(j);
|
||||||
|
const float right = left + barWidth;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (heights[i] >= currentHeight)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
drawList->AddRectFilled(ImVec2(left, currentHeight), ImVec2(right, heights[i]), colors[i]);
|
||||||
|
currentHeight = heights[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
main.cpp
27
main.cpp
@ -37,6 +37,8 @@
|
|||||||
|
|
||||||
#include <exiv2/exiv2.hpp>
|
#include <exiv2/exiv2.hpp>
|
||||||
|
|
||||||
|
#include "lib/histogram.h"
|
||||||
|
|
||||||
struct Args : public argparse::Args {
|
struct Args : public argparse::Args {
|
||||||
std::string &fpath = arg("path to the image");
|
std::string &fpath = arg("path to the image");
|
||||||
};
|
};
|
||||||
@ -228,8 +230,6 @@ Texture LoadTexture(const char * path)
|
|||||||
|
|
||||||
auto exif = printExifData(path);
|
auto exif = printExifData(path);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLenum dataFormat = GL_RGBA;
|
GLenum dataFormat = GL_RGBA;
|
||||||
GLuint textureHandle;
|
GLuint textureHandle;
|
||||||
glGenTextures(1, &textureHandle);
|
glGenTextures(1, &textureHandle);
|
||||||
@ -244,6 +244,23 @@ Texture LoadTexture(const char * path)
|
|||||||
t.channels = channelCount;
|
t.channels = channelCount;
|
||||||
t.exif = exif;
|
t.exif = exif;
|
||||||
|
|
||||||
|
if (t.exif.ImageOrientation == "3") {
|
||||||
|
RotateImage(t);
|
||||||
|
ReloadTexture(t, t.size.x, t.size.y);
|
||||||
|
t = ReloadTexture(t, t.size.y, t.size.x);
|
||||||
|
RotateImage(t);
|
||||||
|
t = ReloadTexture(t, t.size.y, t.size.x);
|
||||||
|
} else if (t.exif.ImageOrientation == "6") {
|
||||||
|
RotateImage(t);
|
||||||
|
t = ReloadTexture(t, t.size.y, t.size.x);
|
||||||
|
} else if (t.exif.ImageOrientation == "8") {
|
||||||
|
RotateImage(t);
|
||||||
|
t = ReloadTexture(t, t.size.y, t.size.x);
|
||||||
|
RotateImage(t);
|
||||||
|
t = ReloadTexture(t, t.size.y, t.size.x);
|
||||||
|
RotateImage(t);
|
||||||
|
t = ReloadTexture(t, t.size.y, t.size.x);
|
||||||
|
}
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -596,6 +613,12 @@ int main(int argc, char* argv[]) {
|
|||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
ImGui::Text("%sx%s", t.exif.ImageDimensionX.c_str(), t.exif.ImageDimensiony.c_str());
|
ImGui::Text("%sx%s", t.exif.ImageDimensionX.c_str(), t.exif.ImageDimensiony.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
ImGui::Text("Orientation");
|
||||||
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
ImGui::Text("%s", t.exif.ImageOrientation.c_str());
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user