mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 06:14:59 +00:00
298 lines
11 KiB
C++
298 lines
11 KiB
C++
/**
|
|
* @file pixel_verification_example.cpp
|
|
* @brief Example: Using PixelDataCSV for screenshot verification in tests
|
|
*
|
|
* This example demonstrates how to use the PNG-to-CSV pixel verification
|
|
* system to validate game screenshots in automated tests.
|
|
*/
|
|
|
|
#include "core/pixel_data_csv.hpp"
|
|
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
|
|
using namespace sdl3cpp::core;
|
|
|
|
// ============================================================================
|
|
// EXAMPLE 1: Basic Image Loading and Inspection
|
|
// ============================================================================
|
|
|
|
void Example_BasicImageLoading() {
|
|
std::cout << "\n=== Example 1: Basic Image Loading ===\n";
|
|
|
|
// Load a CSV file with pixel data
|
|
PixelDataCSV csv;
|
|
if (!csv.LoadFromFile("test_outputs/standalone_cubes_frame.csv")) {
|
|
std::cerr << "Failed to load CSV file\n";
|
|
return;
|
|
}
|
|
|
|
// Print basic properties
|
|
std::cout << "Image dimensions: " << csv.width << "x" << csv.height << "\n";
|
|
std::cout << "Format: " << csv.format << "\n";
|
|
std::cout << "Valid structure: " << (csv.Validate() ? "Yes" : "No") << "\n";
|
|
}
|
|
|
|
// ============================================================================
|
|
// EXAMPLE 2: Pixel-Level Inspection
|
|
// ============================================================================
|
|
|
|
void Example_PixelInspection() {
|
|
std::cout << "\n=== Example 2: Pixel-Level Inspection ===\n";
|
|
|
|
PixelDataCSV csv;
|
|
if (!csv.LoadFromFile("test_outputs/standalone_cubes_frame.csv")) {
|
|
return;
|
|
}
|
|
|
|
// Get pixel at specific location
|
|
auto pixel = csv.GetPixel(512, 384); // Center of 1024x768 image
|
|
if (pixel.has_value()) {
|
|
std::cout << "Center pixel: RGB("
|
|
<< (int)pixel->r << ", " << (int)pixel->g << ", "
|
|
<< (int)pixel->b << "), Alpha: " << (int)pixel->a << "\n";
|
|
std::cout << "Hex color: #" << pixel->ToHex() << "\n";
|
|
}
|
|
|
|
// Sample multiple pixels
|
|
std::cout << "\nCorner pixels:\n";
|
|
auto corners = {
|
|
std::make_pair(0, 0),
|
|
std::make_pair(csv.width - 1, 0),
|
|
std::make_pair(0, csv.height - 1),
|
|
std::make_pair(csv.width - 1, csv.height - 1)
|
|
};
|
|
|
|
for (const auto& [x, y] : corners) {
|
|
if (auto p = csv.GetPixel(x, y)) {
|
|
std::cout << "(" << x << ", " << y << "): RGB("
|
|
<< (int)p->r << ", " << (int)p->g << ", "
|
|
<< (int)p->b << ")\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// EXAMPLE 3: Image Statistics and Analysis
|
|
// ============================================================================
|
|
|
|
void Example_ImageStatistics() {
|
|
std::cout << "\n=== Example 3: Image Statistics ===\n";
|
|
|
|
PixelDataCSV csv;
|
|
if (!csv.LoadFromFile("test_outputs/standalone_cubes_frame.csv")) {
|
|
return;
|
|
}
|
|
|
|
// Get brightness statistics
|
|
auto brightness = csv.GetBrightnessStats();
|
|
std::cout << "Brightness Range: " << (int)brightness.min
|
|
<< " - " << (int)brightness.max << "\n";
|
|
std::cout << "Average brightness: " << std::fixed << std::setprecision(1)
|
|
<< brightness.average << "\n";
|
|
|
|
// Get color distribution
|
|
auto histogram = csv.GetColorHistogram();
|
|
std::cout << "Unique colors: " << histogram.size() << "\n";
|
|
|
|
// Print top 5 most common colors
|
|
std::cout << "Most common colors:\n";
|
|
std::vector<std::pair<uint32_t, uint32_t>> sorted(histogram.begin(),
|
|
histogram.end());
|
|
std::sort(sorted.begin(), sorted.end(),
|
|
[](const auto& a, const auto& b) { return a.second > b.second; });
|
|
|
|
for (size_t i = 0; i < 5 && i < sorted.size(); ++i) {
|
|
uint32_t argb = sorted[i].first;
|
|
uint32_t count = sorted[i].second;
|
|
uint8_t r = (argb >> 16) & 0xFF;
|
|
uint8_t g = (argb >> 8) & 0xFF;
|
|
uint8_t b = argb & 0xFF;
|
|
|
|
std::cout << " #" << std::hex << std::setfill('0')
|
|
<< std::setw(2) << (int)r
|
|
<< std::setw(2) << (int)g
|
|
<< std::setw(2) << (int)b << std::dec
|
|
<< ": " << count << " pixels\n";
|
|
}
|
|
|
|
// Check if image is mostly empty
|
|
std::cout << "Mostly empty (brightness < 30): "
|
|
<< (csv.IsMostlyEmpty(30) ? "Yes" : "No") << "\n";
|
|
std::cout << "Has color variation: "
|
|
<< (csv.HasSignificantVariation(50) ? "Yes" : "No") << "\n";
|
|
|
|
// Opacity information
|
|
std::cout << "Opacity percentage: " << std::fixed << std::setprecision(1)
|
|
<< csv.GetOpacityPercentage() << "%\n";
|
|
}
|
|
|
|
// ============================================================================
|
|
// EXAMPLE 4: Region Analysis
|
|
// ============================================================================
|
|
|
|
void Example_RegionAnalysis() {
|
|
std::cout << "\n=== Example 4: Region Analysis ===\n";
|
|
|
|
PixelDataCSV csv;
|
|
if (!csv.LoadFromFile("test_outputs/standalone_cubes_frame.csv")) {
|
|
return;
|
|
}
|
|
|
|
// Analyze center region where game objects typically are
|
|
uint32_t cx = csv.width / 2;
|
|
uint32_t cy = csv.height / 2;
|
|
uint32_t regionSize = 200;
|
|
|
|
std::cout << "Analyzing " << regionSize << "x" << regionSize
|
|
<< " region at center (" << cx << ", " << cy << "):\n";
|
|
|
|
auto avgColor = csv.GetAverageColor(cx - regionSize / 2, cy - regionSize / 2,
|
|
regionSize, regionSize);
|
|
std::cout << "Average color: RGB(" << (int)avgColor.r << ", "
|
|
<< (int)avgColor.g << ", " << (int)avgColor.b << ")\n";
|
|
|
|
// Count specific colored pixels
|
|
Pixel targetColor(31, 31, 31, 255); // Dark background color
|
|
uint32_t darkPixels = csv.CountPixelsWithTolerance(targetColor, 10);
|
|
std::cout << "Dark background pixels in region: " << darkPixels << "\n";
|
|
|
|
// Get all pixels in region
|
|
auto region = csv.GetPixelRegion(cx - regionSize / 2, cy - regionSize / 2,
|
|
regionSize, regionSize);
|
|
std::cout << "Total pixels in region: " << region.size() << "\n";
|
|
|
|
// Percentage of dark pixels
|
|
double percentage = (100.0 * darkPixels) / region.size();
|
|
std::cout << "Percentage dark: " << std::fixed << std::setprecision(1)
|
|
<< percentage << "%\n";
|
|
}
|
|
|
|
// ============================================================================
|
|
// EXAMPLE 5: Validation for Testing
|
|
// ============================================================================
|
|
|
|
void Example_TestValidation() {
|
|
std::cout << "\n=== Example 5: Test Validation ===\n";
|
|
|
|
PixelDataCSV csv;
|
|
if (!csv.LoadFromFile("test_outputs/standalone_cubes_frame.csv")) {
|
|
return;
|
|
}
|
|
|
|
// Perform validation checks typical in unit tests
|
|
|
|
std::cout << "Validation Checks:\n";
|
|
|
|
// Check 1: Image dimensions
|
|
bool dimensionsValid = csv.VerifyDimensions(1024, 768);
|
|
std::cout << " Dimensions are 1024x768: " << (dimensionsValid ? "PASS" : "FAIL")
|
|
<< "\n";
|
|
|
|
// Check 2: Image is not empty
|
|
bool notEmpty = !csv.IsMostlyEmpty(30);
|
|
std::cout << " Image has content: " << (notEmpty ? "PASS" : "FAIL") << "\n";
|
|
|
|
// Check 3: Image has color variation
|
|
bool hasVariation = csv.HasSignificantVariation(50);
|
|
std::cout << " Image has variation: " << (hasVariation ? "PASS" : "FAIL")
|
|
<< "\n";
|
|
|
|
// Check 4: CSV structure is valid
|
|
bool isValid = csv.Validate();
|
|
std::cout << " CSV structure valid: " << (isValid ? "PASS" : "FAIL") << "\n";
|
|
|
|
// Check 5: Expected color exists
|
|
auto centerPixel = csv.GetPixel(512, 384);
|
|
bool hasPixel = centerPixel.has_value();
|
|
std::cout << " Center pixel exists: " << (hasPixel ? "PASS" : "FAIL") << "\n";
|
|
|
|
// Summary
|
|
int passCount = (dimensionsValid ? 1 : 0) + (notEmpty ? 1 : 0) +
|
|
(hasVariation ? 1 : 0) + (isValid ? 1 : 0) + (hasPixel ? 1 : 0);
|
|
std::cout << "\nOverall: " << passCount << "/5 checks passed\n";
|
|
}
|
|
|
|
// ============================================================================
|
|
// EXAMPLE 6: Comparing Regions
|
|
// ============================================================================
|
|
|
|
void Example_RegionComparison() {
|
|
std::cout << "\n=== Example 6: Region Comparison ===\n";
|
|
|
|
PixelDataCSV csv;
|
|
if (!csv.LoadFromFile("test_outputs/standalone_cubes_frame.csv")) {
|
|
return;
|
|
}
|
|
|
|
// Compare brightness of two regions
|
|
auto topLeftBrightness =
|
|
csv.GetAverageColor(0, 0, 200, 200);
|
|
auto bottomRightBrightness =
|
|
csv.GetAverageColor(csv.width - 200, csv.height - 200, 200, 200);
|
|
|
|
std::cout << "Top-left region average brightness: "
|
|
<< std::fixed << std::setprecision(1)
|
|
<< (0.299 * topLeftBrightness.r + 0.587 * topLeftBrightness.g +
|
|
0.114 * topLeftBrightness.b)
|
|
<< "\n";
|
|
|
|
std::cout << "Bottom-right region average brightness: "
|
|
<< (0.299 * bottomRightBrightness.r + 0.587 * bottomRightBrightness.g +
|
|
0.114 * bottomRightBrightness.b)
|
|
<< "\n";
|
|
|
|
// Compare center regions
|
|
auto centerLeft =
|
|
csv.GetAverageColor(csv.width / 4 - 100, csv.height / 2 - 100, 200, 200);
|
|
auto centerRight =
|
|
csv.GetAverageColor(3 * csv.width / 4 - 100, csv.height / 2 - 100, 200, 200);
|
|
|
|
std::cout << "Left-center color: RGB(" << (int)centerLeft.r << ", "
|
|
<< (int)centerLeft.g << ", " << (int)centerLeft.b << ")\n";
|
|
std::cout << "Right-center color: RGB(" << (int)centerRight.r << ", "
|
|
<< (int)centerRight.g << ", " << (int)centerRight.b << ")\n";
|
|
}
|
|
|
|
// ============================================================================
|
|
// EXAMPLE 7: Detailed Statistics
|
|
// ============================================================================
|
|
|
|
void Example_DetailedStatistics() {
|
|
std::cout << "\n=== Example 7: Detailed Statistics ===\n";
|
|
|
|
PixelDataCSV csv;
|
|
if (!csv.LoadFromFile("test_outputs/standalone_cubes_frame.csv")) {
|
|
return;
|
|
}
|
|
|
|
// Print comprehensive statistics
|
|
std::cout << csv.GetStatisticsString();
|
|
}
|
|
|
|
// ============================================================================
|
|
// Main
|
|
// ============================================================================
|
|
|
|
int main() {
|
|
std::cout << "PNG to CSV Pixel Verification Examples\n";
|
|
std::cout << "======================================\n";
|
|
|
|
try {
|
|
Example_BasicImageLoading();
|
|
Example_PixelInspection();
|
|
Example_ImageStatistics();
|
|
Example_RegionAnalysis();
|
|
Example_TestValidation();
|
|
Example_RegionComparison();
|
|
Example_DetailedStatistics();
|
|
|
|
std::cout << "\n=== All Examples Complete ===\n";
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "Error: " << e.what() << "\n";
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|