📄 ximahist.cpp
字号:
// xImaHist.cpp : histogram functions
/* 28/01/2004 v1.00 - www.xdp.it
* CxImage version 5.99a 08/Feb/2004
*/
#include "ximage.h"
#if CXIMAGE_SUPPORT_DSP
////////////////////////////////////////////////////////////////////////////////
long CxImage::Histogram(long* red, long* green, long* blue, long* gray, long colorspace)
{
if (!pDib) return 0;
RGBQUAD color;
if (red) memset(red,0,256*sizeof(long));
if (green) memset(green,0,256*sizeof(long));
if (blue) memset(blue,0,256*sizeof(long));
if (gray) memset(gray,0,256*sizeof(long));
long xmin,xmax,ymin,ymax;
if (pSelection){
xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
} else {
xmin = ymin = 0;
xmax = head.biWidth; ymax=head.biHeight;
}
for(long y=ymin; y<ymax; y++){
for(long x=xmin; x<xmax; x++){
#if CXIMAGE_SUPPORT_SELECTION
if (SelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
{
switch (colorspace){
case 1:
color = HSLtoRGB(GetPixelColor(x,y));
break;
case 2:
color = YUVtoRGB(GetPixelColor(x,y));
break;
case 3:
color = YIQtoRGB(GetPixelColor(x,y));
break;
case 4:
color = XYZtoRGB(GetPixelColor(x,y));
break;
default:
color = GetPixelColor(x,y);
}
if (red) red[color.rgbRed]++;
if (green) green[color.rgbGreen]++;
if (blue) blue[color.rgbBlue]++;
if (gray) gray[(BYTE)RGB2GRAY(color.rgbRed,color.rgbGreen,color.rgbBlue)]++;
}
}
}
long n=0;
for (int i=0; i<256; i++){
if (red && red[i]>n) n=red[i];
if (green && green[i]>n) n=green[i];
if (blue && blue[i]>n) n=blue[i];
if (gray && gray[i]>n) n=gray[i];
}
return n;
}
////////////////////////////////////////////////////////////////////////////////
// HistogramStretch function by <dave> : dave(at)posortho(dot)com and <nipper>
bool CxImage::HistogramStretch(long method)
{
if (!pDib) return false;
if ((head.biBitCount==8) && IsGrayScale()){
// get min/max info
BYTE minc = 255, maxc = 0;
BYTE gray;
double dbScaler = 50.0/head.biHeight;
for (long y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(y*dbScaler);
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++) {
gray = GetPixelIndex(x, y);
if (gray < minc) minc = gray;
if (gray > maxc) maxc = gray;
}
}
if (minc == 0 && maxc == 255) return true;
// calculate LUT
BYTE lut[256];
BYTE range = maxc - minc;
if (range != 0){
for (long x = minc; x <= maxc; x++){
lut[x] = (BYTE)(255 * (x - minc) / range);
}
} else lut[minc] = minc;
for (y=0; y<head.biHeight; y++) {
if (info.nEscape) break;
info.nProgress = (long)(50.0+y*dbScaler);
for (long x=0; x<head.biWidth; x++)
{
SetPixelIndex(x, y, lut[GetPixelIndex(x, y)]);
}
}
} else {
switch(method){
case 1:
{ // <nipper>
// get min/max info
BYTE minc = 255, maxc = 0;
RGBQUAD color;
for (long y=0; y<head.biHeight; y++)
{
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++)
{
color = GetPixelColor(x, y);
if (color.rgbRed < minc) minc = color.rgbRed;
if (color.rgbBlue < minc) minc = color.rgbBlue;
if (color.rgbGreen < minc) minc = color.rgbGreen;
if (color.rgbRed > maxc) maxc = color.rgbRed;
if (color.rgbBlue > maxc) maxc = color.rgbBlue;
if (color.rgbGreen > maxc) maxc = color.rgbGreen;
}
}
if (minc == 0 && maxc == 255)
return true;
// calculate LUT
BYTE lut[256];
BYTE range = maxc - minc;
if (range != 0){
for (long x = minc; x <= maxc; x++){
lut[x] = (BYTE)(255 * (x - minc) / range);
}
} else lut[minc] = minc;
// normalize image
double dbScaler = 100.0/head.biHeight;
for (y=0; y<head.biHeight; y++) {
if (info.nEscape) break;
info.nProgress = (long)(y*dbScaler);
for (long x=0; x<head.biWidth; x++)
{
color = GetPixelColor(x, y);
color.rgbRed = lut[color.rgbRed];
color.rgbBlue = lut[color.rgbBlue];
color.rgbGreen = lut[color.rgbGreen];
SetPixelColor(x, y, color);
}
}
}
break;
case 2:
{ // <nipper>
// get min/max info
BYTE minR = 255, maxR = 0;
BYTE minG = 255, maxG = 0;
BYTE minB = 255, maxB = 0;
RGBQUAD color;
for (long y=0; y<head.biHeight; y++)
{
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++)
{
color = GetPixelColor(x, y);
if (color.rgbRed < minR) minR = color.rgbRed;
if (color.rgbBlue < minB) minB = color.rgbBlue;
if (color.rgbGreen < minG) minG = color.rgbGreen;
if (color.rgbRed > maxR) maxR = color.rgbRed;
if (color.rgbBlue > maxB) maxB = color.rgbBlue;
if (color.rgbGreen > maxG) maxG = color.rgbGreen;
}
}
if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255)
return true;
// calculate LUT
BYTE lutR[256];
BYTE range = maxR - minR;
if (range != 0) {
for (long x = minR; x <= maxR; x++){
lutR[x] = (BYTE)(255 * (x - minR) / range);
}
} else lutR[minR] = minR;
BYTE lutG[256];
range = maxG - minG;
if (range != 0) {
for (long x = minG; x <= maxG; x++){
lutG[x] = (BYTE)(255 * (x - minG) / range);
}
} else lutG[minG] = minG;
BYTE lutB[256];
range = maxB - minB;
if (range != 0) {
for (long x = minB; x <= maxB; x++){
lutB[x] = (BYTE)(255 * (x - minB) / range);
}
} else lutB[minB] = minB;
// normalize image
double dbScaler = 100.0/head.biHeight;
for (y=0; y<head.biHeight; y++)
{
info.nProgress = (long)(y*dbScaler);
if (info.nEscape) break;
for (long x=0; x<head.biWidth; x++)
{
color = GetPixelColor(x, y);
color.rgbRed = lutR[color.rgbRed];
color.rgbBlue = lutB[color.rgbBlue];
color.rgbGreen = lutG[color.rgbGreen];
SetPixelColor(x, y, color);
}
}
}
break;
default:
{ // <dave>
// S = ( R - C ) ( B - A / D - C )
double alimit = 0.0;
double blimit = 255.0;
double lowerc = 255.0;
double upperd = 0.0;
double tmpGray;
RGBQUAD color;
RGBQUAD yuvClr;
double stretcheds;
if ( head.biClrUsed == 0 ){
long x, y, xmin, xmax, ymin, ymax;
xmin = ymin = 0;
xmax = head.biWidth;
ymax = head.biHeight;
for( y = ymin; y < ymax; y++ ){
info.nProgress = (long)(50*y/ymax);
if (info.nEscape) break;
for( x = xmin; x < xmax; x++ ){
color = GetPixelColor( x, y );
tmpGray = RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if ( tmpGray < lowerc ) lowerc = tmpGray;
if ( tmpGray > upperd ) upperd = tmpGray;
}
}
if (upperd==lowerc) return false;
for( y = ymin; y < ymax; y++ ){
info.nProgress = (long)(50+50*y/ymax);
if (info.nEscape) break;
for( x = xmin; x < xmax; x++ ){
color = GetPixelColor( x, y );
yuvClr = RGBtoYUV(color);
// Stretch Luminance
tmpGray = (double)yuvClr.rgbRed;
stretcheds = (double)(tmpGray - lowerc) * ( (blimit - alimit) / (upperd - lowerc) ); // + alimit;
if ( stretcheds < 0.0 ) stretcheds = 0.0;
else if ( stretcheds > 255.0 ) stretcheds = 255.0;
yuvClr.rgbRed = (BYTE)stretcheds;
color = YUVtoRGB(yuvClr);
SetPixelColor( x, y, color );
}
}
} else {
DWORD j;
for( j = 0; j < head.biClrUsed; j++ ){
color = GetPaletteColor( (BYTE)j );
tmpGray = RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue);
if ( tmpGray < lowerc ) lowerc = tmpGray;
if ( tmpGray > upperd ) upperd = tmpGray;
}
if (upperd==lowerc) return false;
for( j = 0; j < head.biClrUsed; j++ ){
color = GetPaletteColor( (BYTE)j );
yuvClr = RGBtoYUV( color );
// Stretch Luminance
tmpGray = (double)yuvClr.rgbRed;
stretcheds = (double)(tmpGray - lowerc) * ( (blimit - alimit) / (upperd - lowerc) ); // + alimit;
if ( stretcheds < 0.0 ) stretcheds = 0.0;
else if ( stretcheds > 255.0 ) stretcheds = 255.0;
yuvClr.rgbRed = (BYTE)stretcheds;
color = YUVtoRGB(yuvClr);
SetPaletteColor( (BYTE)j, color );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -