//--------------------------------------------------------------------------- #include #pragma hdrstop #include "TClrUtil.h" #include "grouping_lib1.h" #include "LogData.h" //--------------------------------------------------------------------------- #define involution(a,b) fabs(a-b)*fabs(a-b) //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- bool __fastcall grouping(TUnionBitmap *previewBitmap, TList *ListOfColor, TStatusProgress *progress) { TCursor cur; if(!ListOfColor->Count) return false; BEGIN_LOG(""); Byte *ptr, *ptrU, *ptrD; Byte *Aptr1, *AptrU, *AptrD, *Aptr2; Byte DummyColor[3]; Byte *tempMidd, *tempDown; Byte *tempApMidd, *tempApDown; long items_red = 0, items_green = 0, items_blue = 0; int x, y, height, width; int MinSubColor; int Dummy; int Sx,Sy; cur = Screen->Cursor; Screen->Cursor = crHourGlass; height = previewBitmap->Height; width = previewBitmap->Width; TUnionBitmap *tempBitmap = new TUnionBitmap; tempBitmap->Create(width, height, 24); tempBitmap->Copy(previewBitmap, SRCCOPY); previewBitmap->PartialUndo->RangeSaveUndo(0, 0, previewBitmap->Width, previewBitmap->Height); //by linuxjun progress->Maximum = height * 3; previewBitmap->StartScanLine(); tempBitmap->StartScanLine(); for(y=0;yGetScanLine(y); Aptr1 = tempBitmap->GetScanLine(y); for(x=0;xPutScanLine(y); progress->Position = y ; } previewBitmap->StopScanLine(); tempBitmap->StopScanLine(); //------------------------------------------------------------------------- // Blur¸¦ ÁÖ´Â ºÎºÐ // A A previewBitmap->StartScanLine(); // B A tempBitmap->StartScanLineN(2); for(y=0;yGetScanLine(y); if (y==0) { AptrD = tempBitmap->GetScanLineN( y, y%2); } else { Aptr1 = tempApDown; AptrD = tempBitmap->GetScanLineN( y, y%2); } tempApDown=AptrD; if(y >=1) { for(x=0;xPutScanLine(y); progress->Position = height + y; } previewBitmap->StopScanLine(); tempBitmap->StopScanLine(); //--------------------------------------------------------------------------- // °¢ Colorº° Intensity¸¦ ¸¸µé¾î ÁÖ´Â ºÎºÐ int IntensPC[20][100][3]; for(int M = 0; M < 10; M++) { for(int Va = 0; Va< ListOfColor->Count; Va++) { items_red = (*(TColor*)(ListOfColor->Items[Va])) & 0xFF; items_green = (*((TColor*)(ListOfColor->Items[Va])) >> 8) & 0xFF; items_blue = (*((TColor*)(ListOfColor->Items[Va])) >> 16) & 0xFF; if(M%2 == 0) { IntensPC[M][Va][0] = (255-items_blue)*M/40 + items_blue; IntensPC[M][Va][1] = (255-items_green)*M/40 + items_green; IntensPC[M][Va][2] = (255-items_red)*M/40 + items_red; } if(M%2 == 1) { IntensPC[M][Va][0] = -(items_blue)*(M+1)/40 + items_blue; IntensPC[M][Va][1] = -(items_green)*(M+1)/40 + items_green; IntensPC[M][Va][2] = -(items_red)*(M+1)/40 + items_red; } } } //--------------------------------------------------------------------------- previewBitmap->StartScanLine(); tempBitmap->StartScanLine(); for(y=0;yGetScanLine(y); Aptr1 = tempBitmap->GetScanLine(y); for(x=0;xCount; Va++) { for(int M = 0; M < 10; M++) { Dummy = (IntensPC[M][Va][0] -DummyColor[0])*(IntensPC[M][Va][0] -DummyColor[0]) + (IntensPC[M][Va][1] -DummyColor[1])*(IntensPC[M][Va][1] -DummyColor[1]) +(IntensPC[M][Va][2] -DummyColor[2])*(IntensPC[M][Va][2] -DummyColor[2]) ; if( MinSubColor > Dummy) { MinSubColor= Dummy; Aptr1[3*x+2] = Va; } } } Aptr1[3*x] = sqrt(MinSubColor)/23; Aptr1[3*x+1] = 0; } previewBitmap->PutScanLine(y); tempBitmap->PutScanLine(y); progress->Position = height * 2 + y; } previewBitmap->StopScanLine(); tempBitmap->StopScanLine(); //------------------------------------------------------------------------- previewBitmap->StartScanLineN(3); tempBitmap->StartScanLineN(3); for(int M = 0; M < 20; M++) { for(y=0;yGetScanLineN( y, y%3); AptrU = tempBitmap->GetScanLineN( y, y%3); } else if (y==1) { ptr = previewBitmap->GetScanLineN( y, y%3); Aptr1 = tempBitmap->GetScanLineN( y, y%3); } else if (y==2) { ptrD = previewBitmap->GetScanLineN( y, y%3); AptrD = tempBitmap->GetScanLineN( y, y%3); } else { ptrU = tempMidd; ptr = tempDown; ptrD = previewBitmap->GetScanLineN( y, y%3); AptrU = tempApMidd; Aptr1 = tempApDown; AptrD = tempBitmap->GetScanLineN( y, y%3); } tempMidd=ptr; tempDown=ptrD; tempApMidd=Aptr1; tempApDown=AptrD; if (y >= 2) { for(x=1;x Dummy) { MinSubColor = Dummy; Sx = j; Sy = -1; } Dummy = (ptr[3*(x+j)]-ptr[3*x])*(ptr[3*(x+j)]-ptr[3*x])+(ptr[3*(x+j)+1]-ptr[3*x+1])*(ptr[3*(x+j)+1]-ptr[3*x+1])+(ptr[3*(x+j)+2]-ptr[3*x+2])*(ptr[3*(x+j)+2]-ptr[3*x+2]); if(MinSubColor > Dummy) { MinSubColor = Dummy; Sx = j; Sy = 0; } Dummy = (ptrD[3*(x+j)]-ptr[3*x])*(ptrD[3*(x+j)]-ptr[3*x])+(ptrD[3*(x+j)+1]-ptr[3*x+1])*(ptrD[3*(x+j)+1]-ptr[3*x+1])+(ptrD[3*(x+j)+2]-ptr[3*x+2])*(ptrD[3*(x+j)+2]-ptr[3*x+2]); if(MinSubColor > Dummy) { MinSubColor = Dummy; Sx = j; Sy = 1; } } if(Sy == -1) { ptr[3*x] = (*((TColor*)(ListOfColor->Items[AptrU[3*(x+Sx)+2]])) >> 16) & 0xFF; ptr[3*x+1] = (*((TColor*)(ListOfColor->Items[AptrU[3*(x+Sx)+2]])) >> 8) & 0xFF; ptr[3*x+2] = (*(TColor*)(ListOfColor->Items[AptrU[3*(x+Sx)+2]])) & 0xFF; } else if(Sy == 0) { ptr[3*x] = (*((TColor*)(ListOfColor->Items[Aptr1[3*(x+Sx)+2]])) >> 16) & 0xFF; ptr[3*x+1] = (*((TColor*)(ListOfColor->Items[Aptr1[3*(x+Sx)+2]])) >> 8) & 0xFF; ptr[3*x+2] = (*(TColor*)(ListOfColor->Items[Aptr1[3*(x+Sx)+2]])) & 0xFF; } else { ptr[3*x] = (*((TColor*)(ListOfColor->Items[AptrD[3*(x+Sx)+2]])) >> 16) & 0xFF; ptr[3*x+1] = (*((TColor*)(ListOfColor->Items[AptrD[3*(x+Sx)+2]])) >> 8) & 0xFF; ptr[3*x+2] = (*(TColor*)(ListOfColor->Items[AptrD[3*(x+Sx)+2]])) & 0xFF; } //ù¹øÂ° Pixel°ú ¸¶Áö¸· PixelÀº 󸮸¦ ÇÏÁö ¸øÇϱ⠶§¹®¿¡ ¿·ÀÇ pixel°ªÀ¸·Î ´ëüÇß´Ù. if (x == 1) { ptr[0] =ptr[3]; ptr[1] =ptr[4]; ptr[2] =ptr[5]; } else if ( x== width-2) { ptr[3*(x+1)] = ptr[3*x]; ptr[3*(x+1)+1] = ptr[3*x+1]; ptr[3*(x+1)+2] = ptr[3*x+2]; } } } // ù¹øÂ° Line°ú ¸¶Áö¸· LineÀº 󸮸¦ ÇÏÁö ¸øÇϱ⠶§¹®¿¡ ¾Æ·¡/À­LineÀ¸·Î CopyÇß´Ù. if (y-1 == 1) { memcpy(ptrU, ptr, sizeof(Byte)*width*3); previewBitmap->PutScanLineN( y-2, (y-2)%3); } else if (y-1 == height-2 ) { memcpy(ptrD, ptr, sizeof(Byte)*width*3); previewBitmap->PutScanLineN( y, y%3); } previewBitmap->PutScanLineN( y-1, (y-1)%3); } // ¿©±â±îÁö if (y >= 2)... } } progress->Position = height * 3; previewBitmap->StopScanLine(); tempBitmap->StopScanLine(); progress->End(); Screen->Cursor = cur; delete tempBitmap; END_LOG; return true; } //--------------------------------------------------------------------------- float diffusion_loss = 0.2; //--------------------------------------------------------------------------- double __fastcall find_gradation_pos(Byte *p, Byte *grad_s, Byte *grad_e){ int v1[3] = {grad_e[0]-grad_s[0], grad_e[1]-grad_s[1], grad_e[2]-grad_s[2]}; int vp[3] = { p[0]-grad_s[0], p[1]-grad_s[1], p[2]-grad_s[2]}; double len1 = v1[0]*v1[0]+v1[1]*v1[1]+v1[2]*v1[2]; double dot = v1[0]*vp[0]+v1[1]*vp[1]+v1[2]*vp[2]; if(len1==0){ return 0; } else { return dot/len1; } } //--------------------------------------------------------------------------- void __fastcall gradation(TUnionBitmap *previewBitmap, TUnionBitmap *blurBitmap, TPWorkArea *WorkArea, TList *ListOfColor){ if(!ListOfColor->Count) return; BEGIN_LOG(""); RECT waRange = WorkArea->Range; int waWidth = waRange.right - waRange.left; int waHeight = waRange.bottom - waRange.top; int x, y; int cnt = ListOfColor->Count; int halftone_index; double grad_length1; double grad_length2; float *gradation_pos;//0¿¡¼­ 1»çÀÌÀÇ °ª//0À̸é ù»ö//1ÀÌ¸é ³¡»ö Byte *selected_color; Byte *gradation_colors = new Byte[cnt*3]; Byte *pPreview; Byte *pBlur, *pBlur2; Byte *pMask; TColor *cp; for(int i=0;iItems[i]; *(gradation_colors+3*i+2) = (*cp ) & 0xFF ; *(gradation_colors+3*i+1) = (*cp>>8 ) & 0xFF; *(gradation_colors+3*i ) = (*cp>>16) & 0xFF; } selected_color = (Byte *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Byte)*(blurBitmap->Width)*(blurBitmap->Height)); gradation_pos = (float *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(float)*(blurBitmap->Width)*(blurBitmap->Height)); blurBitmap->StartScanLine(); previewBitmap->StartScanLine(); if(WorkArea->Mask) { WorkArea->Mask->StartScanLine(); for (y = 0; y < waHeight; y++ ) { pPreview = previewBitmap->GetScanLine(y + waRange.top, waRange.left, waWidth) + 3 * waRange.left; pMask = WorkArea->Mask->GetScanLine(y); // 1 bit mask°¡ µÇ¾ú´Ù ¶Ç´Â ¾Æ´Ï´Ù (on/off) for (x = 0; x < waWidth; x++ ) { // 24 bits ÇϳªÀÇ »öÀ» Ç¥Çö(8, 8, 8) if (pMask[x >> 3] & (0x80 >> (x & 7))) { // x>>3 == x/8, x&7={0,1,2,3,4,5,6,7} for(int i=0;iWidth+(x+waRange.left)] = true; break; } } } pPreview += 3; } } WorkArea->Mask->StopScanLine(); } else { for (y = 0; y < previewBitmap->Height; y++ ) { pPreview = previewBitmap->GetScanLine(y); for (x = 0; x < previewBitmap->Width; x++ ) { for(int i=0;iWidth+x] = true; break; } } pPreview += 3; } } } float pos; for (y = 0; y < blurBitmap->Height; y++ ) { pBlur = blurBitmap->GetScanLine(y); for (x = 0; x < blurBitmap->Width; x++ ) { pos = find_gradation_pos(pBlur,gradation_colors,gradation_colors+3*(cnt-1)); if(pos>1) pos=1; if(pos<0) pos=0; gradation_pos[y*blurBitmap->Width+x] = pos; pBlur += 3; } } float error; //Halftoning //Floyd-Steinberg error diffusion float loss = diffusion_loss; for (y = 0; y < blurBitmap->Height-1; y++ ) { for (x = 0; x < blurBitmap->Width-1; x++ ) { if(selected_color[y*blurBitmap->Width+x]) { if(gradation_pos[y*blurBitmap->Width+x]>0.5){ error = gradation_pos[y*blurBitmap->Width+x] - 1.0; } else { error = gradation_pos[y*blurBitmap->Width+x]; } gradation_pos[(y )*blurBitmap->Width+x+1] += 3.0/8.0*error*(1.0-loss); gradation_pos[(y+1)*blurBitmap->Width+x ] += 3.0/8.0*error*(1.0-loss); gradation_pos[(y+1)*blurBitmap->Width+x+1] += 2.0/8.0*error*(1.0-loss); } } } for (y = 0; y < previewBitmap->Height; y++ ) { pPreview = previewBitmap->GetScanLine(y); for (x = 0; x < previewBitmap->Width; x++ ) { if(selected_color[y*blurBitmap->Width+x]) { if(gradation_pos[y*blurBitmap->Width+x]>0.5){//>0.25+(rand()%100)/200.0){ pPreview[0] = gradation_colors[3*(cnt-1)+0]; pPreview[1] = gradation_colors[3*(cnt-1)+1]; pPreview[2] = gradation_colors[3*(cnt-1)+2]; } else { pPreview[0] = gradation_colors[0]; pPreview[1] = gradation_colors[1]; pPreview[2] = gradation_colors[2]; } } pPreview += 3; } previewBitmap->PutScanLine(y); } previewBitmap->StopScanLine(); blurBitmap->StopScanLine(); if(selected_color) HeapFree(GetProcessHeap(), 0, selected_color); if(gradation_pos) HeapFree(GetProcessHeap(), 0, gradation_pos); delete [] gradation_colors; END_LOG; } //---------------------------------------------------------------------------