📄 ximatran.cpp
字号:
}
}
break;
}
case 4:
{
//Jarvis, Judice and Ninke error diffusion (Thanks to Franco Gerevini)
int TotalCoeffSum = 48;
long error, nlevel, coeff=1;
BYTE level;
for (long y = 0; y < head.biHeight; y++) {
info.nProgress = (long)(100 * y / head.biHeight);
if (info.nEscape)
break;
for (long x = 0; x < head.biWidth; x++) {
level = BlindGetPixelIndex(x, y);
if (level > 128) {
tmp.SetPixelIndex(x, y, 1);
error = level - 255;
} else {
tmp.SetPixelIndex(x, y, 0);
error = level;
}
nlevel = GetPixelIndex(x + 1, y) + (error * 7) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(x + 1, y, level);
nlevel = GetPixelIndex(x + 2, y) + (error * 5) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(x + 2, y, level);
int i;
for (i = -2; i < 3; i++) {
switch (i) {
case -2:
coeff = 3;
break;
case -1:
coeff = 5;
break;
case 0:
coeff = 7;
break;
case 1:
coeff = 5;
break;
case 2:
coeff = 3;
break;
}
nlevel = GetPixelIndex(x + i, y + 1) + (error * coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(x + i, y + 1, level);
}
for (i = -2; i < 3; i++) {
switch (i) {
case -2:
coeff = 1;
break;
case -1:
coeff = 3;
break;
case 0:
coeff = 5;
break;
case 1:
coeff = 3;
break;
case 2:
coeff = 1;
break;
}
nlevel = GetPixelIndex(x + i, y + 2) + (error * coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(x + i, y + 2, level);
}
}
}
break;
}
case 5:
{
//Sierra error diffusion (Thanks to Franco Gerevini)
int TotalCoeffSum = 32;
long error, nlevel, coeff=1;
BYTE level;
for (long y = 0; y < head.biHeight; y++) {
info.nProgress = (long)(100 * y / head.biHeight);
if (info.nEscape)
break;
for (long x = 0; x < head.biWidth; x++) {
level = BlindGetPixelIndex(x, y);
if (level > 128) {
tmp.SetPixelIndex(x, y, 1);
error = level - 255;
} else {
tmp.SetPixelIndex(x, y, 0);
error = level;
}
nlevel = GetPixelIndex(x + 1, y) + (error * 5) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(x + 1, y, level);
nlevel = GetPixelIndex(x + 2, y) + (error * 3) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(x + 2, y, level);
int i;
for (i = -2; i < 3; i++) {
switch (i) {
case -2:
coeff = 2;
break;
case -1:
coeff = 4;
break;
case 0:
coeff = 5;
break;
case 1:
coeff = 4;
break;
case 2:
coeff = 2;
break;
}
nlevel = GetPixelIndex(x + i, y + 1) + (error * coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(x + i, y + 1, level);
}
for (i = -1; i < 2; i++) {
switch (i) {
case -1:
coeff = 2;
break;
case 0:
coeff = 3;
break;
case 1:
coeff = 2;
break;
}
nlevel = GetPixelIndex(x + i, y + 2) + (error * coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(x + i, y + 2, level);
}
}
}
break;
}
case 6:
{
//Stevenson and Arce error diffusion (Thanks to Franco Gerevini)
int TotalCoeffSum = 200;
long error, nlevel;
BYTE level;
for (long y = 0; y < head.biHeight; y++) {
info.nProgress = (long)(100 * y / head.biHeight);
if (info.nEscape)
break;
for (long x = 0; x < head.biWidth; x++) {
level = BlindGetPixelIndex(x, y);
if (level > 128) {
tmp.SetPixelIndex(x, y, 1);
error = level - 255;
} else {
tmp.SetPixelIndex(x, y, 0);
error = level;
}
int tmp_index_x = x + 2;
int tmp_index_y = y;
int tmp_coeff = 32;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x - 3;
tmp_index_y = y + 1;
tmp_coeff = 12;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x - 1;
tmp_coeff = 26;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x + 1;
tmp_coeff = 30;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x + 3;
tmp_coeff = 16;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x - 2;
tmp_index_y = y + 2;
tmp_coeff = 12;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x;
tmp_coeff = 26;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x + 2;
tmp_coeff = 12;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x - 3;
tmp_index_y = y + 3;
tmp_coeff = 5;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x - 1;
tmp_coeff = 12;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x + 1;
tmp_coeff = 12;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
tmp_index_x = x + 3;
tmp_coeff = 5;
nlevel = GetPixelIndex(tmp_index_x, tmp_index_y) + (error * tmp_coeff) / TotalCoeffSum;
level = (BYTE)min(255, max(0, (int)nlevel));
SetPixelIndex(tmp_index_x, tmp_index_y, level);
}
}
break;
}
case 7:
{
// Bayer ordered dither
int order = 4;
//create Bayer matrix
if (order>4) order = 4;
int size = (1 << (2*order));
BYTE* Bmatrix = (BYTE*) malloc(size * sizeof(BYTE));
for(int i = 0; i < size; i++) {
int n = order;
int x = i / n;
int y = i % n;
int dither = 0;
while (n-- > 0){
dither = (((dither<<1)|((x&1) ^ (y&1)))<<1) | (y&1);
x >>= 1;
y >>= 1;
}
Bmatrix[i] = (BYTE)(dither);
}
int scale = max(0,(8-2*order));
int level;
for (long y=0;y<head.biHeight;y++){
info.nProgress = (long)(100*y/head.biHeight);
if (info.nEscape) break;
for (long x=0;x<head.biWidth;x++){
level = BlindGetPixelIndex(x,y) >> scale;
if(level > Bmatrix[ (x % order) + order * (y % order) ]){
tmp.SetPixelIndex(x,y,1);
} else {
tmp.SetPixelIndex(x,y,0);
}
}
}
free(Bmatrix);
break;
}
default:
{
// Floyd-Steinberg error diffusion (Thanks to Steve McMahon)
long error,nlevel,coeff=1;
BYTE level;
for (long y=0;y<head.biHeight;y++){
info.nProgress = (long)(100*y/head.biHeight);
if (info.nEscape) break;
for (long x=0;x<head.biWidth;x++){
level = BlindGetPixelIndex(x,y);
if (level > 128){
tmp.SetPixelIndex(x,y,1);
error = level-255;
} else {
tmp.SetPixelIndex(x,y,0);
error = level;
}
nlevel = GetPixelIndex(x+1,y) + (error * 7)/16;
level = (BYTE)min(255,max(0,(int)nlevel));
SetPixelIndex(x+1,y,level);
for(int i=-1; i<2; i++){
switch(i){
case -1:
coeff=3; break;
case 0:
coeff=5; break;
case 1:
coeff=1; break;
}
nlevel = GetPixelIndex(x+i,y+1) + (error * coeff)/16;
level = (BYTE)min(255,max(0,(int)nlevel));
SetPixelIndex(x+i,y+1,level);
}
}
}
}
}
tmp.SetPaletteColor(0,0,0,0);
tmp.SetPaletteColor(1,255,255,255);
Transfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
/**
* CropRotatedRectangle
* \param topx,topy : topmost and leftmost point of the rectangle
(topmost, and if there are 2 topmost points, the left one)
* \param width : size of the right hand side of rect, from (topx,topy) roundwalking clockwise
* \param height : size of the left hand side of rect, from (topx,topy) roundwalking clockwise
* \param angle : angle of the right hand side of rect, from (topx,topy)
* \param iDst : pointer to destination image (if 0, this image is modified)
* \author [VATI]
*/
bool CxImage::CropRotatedRectangle( long topx, long topy, long width, long height, float angle, CxImage* iDst)
{
if (!pDib) return false;
long startx,starty,endx,endy;
double cos_angle = cos(angle/*/57.295779513082320877*/);
double sin_angle = sin(angle/*/57.295779513082320877*/);
// if there is nothing special, call the original Crop():
if ( fabs(angle)<0.0002 )
return Crop( topx, topy, topx+width, topy+height, iDst);
startx = min(topx, topx - (long)(sin_angle*(double)height));
endx = topx + (long)(cos_angle*(double)width);
endy = topy + (long)(cos_angle*(double)height + sin_angle*(double)width);
// check: corners of the rectangle must be inside
if ( IsInside( startx, topy )==false ||
IsInside( endx, endy ) == false )
return false;
// first crop to bounding rectangle
CxImage tmp(*this, true, false, true);
// tmp.Copy(*this, true, false, true);
if (!tmp.IsValid()){
strcpy(info.szLastError,tmp.GetLastError());
return false;
}
if (!tmp.Crop( startx, topy, endx, endy)){
strcpy(info.szLastError,tmp.GetLastError());
return false;
}
// the midpoint of the image now became the same as the midpoint of the rectangle
// rotate new image with minus angle amount
if ( false == tmp.Rotate( (float)(-angle*57.295779513082320877) ) ) // Rotate expects angle in degrees
return false;
// crop rotated image to the original selection rectangle
endx = (tmp.head.biWidth+width)/2;
startx = (tmp.head.biWidth-width)/2;
starty = (tmp.head.biHeight+height)/2;
endy = (tmp.head.biHeight-height)/2;
if ( false == tmp.Crop( startx, starty, endx, endy ) )
return false;
if (iDst) iDst->Transfer(tmp);
else Transfer(tmp);
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::Crop(const RECT& rect, CxImage* iDst)
{
return Crop(rect.left, rect.top, rect.right, rect.bottom, iDst);
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::Crop(long left, long top, long right, long bottom, CxImage* iDst)
{
if (!pDib) return false;
long startx = max(0L,min(left,head.biWidth));
long endx = max(0L,min(right,head.biWidth));
long starty = head.biHeight -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -