/* * AlphaImage * * Alpha Channel 󸮸¦ À§ÇÑ Image Component * ÇöÀç´Â TGAÆÄÀϸ¸ Áö¿øÇÔ * * Cuperido @ Nineteam */ #include #include #pragma hdrstop #include "AlphaImage.h" #pragma package(smart_init) //--------------------------------------------------------------------------- static inline void ValidCtrCheck(TAlphaImage *) { new TAlphaImage(NULL); } //--------------------------------------------------------------------------- __fastcall TAlphaImage::TAlphaImage(TComponent* Owner) : TCustomImage(Owner) { FPicture_Alpha = new Graphics::TPicture; } //--------------------------------------------------------------------------- __fastcall TAlphaImage::~TAlphaImage() { delete FPicture_Alpha; } //--------------------------------------------------------------------------- void __fastcall TAlphaImage::Assign_Picture_Alpha(Graphics::TPicture *piImage) { FPicture_Alpha->Assign(piImage); } //--------------------------------------------------------------------------- void __fastcall TAlphaImage::LoadTGAFromFile(AnsiString stFilename) { std::auto_ptr BUFFER(new TMemoryStream); RGBTRIPLE *rtColor, *rtAlphaColor; unsigned char chTemp, chAlphaValue; unsigned short shTemp; int itTemp, itWidth, itHeight, itX, itY; try { BUFFER->Clear(); BUFFER->LoadFromFile(stFilename); } catch(...) { return; } BUFFER->Read(&shTemp, 2); if(shTemp) return; // Ư¼ö Çì´õ¼º TGA´Â ÀÐÁö ¾ÊÀ½ BUFFER->Read(&chTemp, 1); if(chTemp != 2) return; // True Color°¡ ¾Æ´Ï¸é ÀÐÁö ¾ÊÀ½ BUFFER->Seek(12, soFromBeginning); BUFFER->Read(&shTemp, 2); // Width Àбâ itWidth = shTemp; BUFFER->Read(&shTemp, 2); // Height Àбâ itHeight = shTemp; BUFFER->Read(&chTemp, 1); if(chTemp != 32) return; // 32Bit Color°¡ ¾Æ´Ï¸é ÀÐÁö ¾ÊÀ½ BUFFER->Read(&chTemp, 1); if(chTemp != 8) return; // Alpha ChannelÀÌ ¾ø°Å³ª 8 Bit°¡ ³ÑÀ¸¸é ÀÐÁö ¾ÊÀ½ // Image ¼³Á¤ Width = itWidth; Height = itHeight; Picture->Bitmap->Width = itWidth; Picture->Bitmap->Height = itWidth; Picture->Bitmap->PixelFormat = pf24bit; Picture_Alpha->Bitmap->Width = itWidth; Picture_Alpha->Bitmap->Height = itWidth; Picture_Alpha->Bitmap->PixelFormat = pf24bit; for(itY = itHeight - 1; itY >= 0; itY --) { rtColor = (RGBTRIPLE *)Picture->Bitmap->ScanLine[itY]; rtAlphaColor = (RGBTRIPLE *)Picture_Alpha->Bitmap->ScanLine[itY]; for(itX = 0; itX < itWidth; itX ++) { BUFFER->Read(&rtColor->rgbtBlue, 1); BUFFER->Read(&rtColor->rgbtGreen, 1); BUFFER->Read(&rtColor->rgbtRed, 1); BUFFER->Read(&chAlphaValue, 1); rtAlphaColor->rgbtBlue = chAlphaValue; rtAlphaColor->rgbtGreen = chAlphaValue; rtAlphaColor->rgbtRed = chAlphaValue; rtColor ++; rtAlphaColor ++; } } } //--------------------------------------------------------------------------- void __fastcall TAlphaImage::LoadFromFile(AnsiString stFilename) { if(ExtractFileExt(stFilename).UpperCase() == ".TGA") { LoadTGAFromFile(stFilename); } else { Picture->LoadFromFile(stFilename); } } //--------------------------------------------------------------------------- void __fastcall TAlphaImage::SaveToFile(AnsiString stFilename) { std::auto_ptr BUFFER(new TMemoryStream); RGBTRIPLE *rtColor, *rtAlphaColor; char caHeader[18]; unsigned char chAlphaValue; int itX, itY; unsigned char chRed, chGreen, chBlue; srTGAHeader srHeader; if(Picture->Bitmap->PixelFormat != pf24bit) return; if(Picture_Alpha->Bitmap->PixelFormat != pf24bit) return; FillMemory(&srHeader, sizeof(srHeader), 0); srHeader.ImageType = 2; srHeader.Width = Width; srHeader.Height = Height; srHeader.Bits = 32; srHeader.AlphaBits = 8; BUFFER->Clear(); BUFFER->Write(&srHeader, sizeof(srHeader)); for(itY = Height - 1; itY >= 0; itY --) { rtColor = (RGBTRIPLE *)Picture->Bitmap->ScanLine[itY]; rtAlphaColor = (RGBTRIPLE *)Picture_Alpha->Bitmap->ScanLine[itY]; for(itX = 0; itX < Width; itX ++) { chAlphaValue = rtAlphaColor->rgbtBlue; if(chAlphaValue) { chRed = ((rtColor->rgbtRed - (255 - chAlphaValue)) * 255 / chAlphaValue) >= 0 ? ((rtColor->rgbtRed - (255 - chAlphaValue)) * 255 / chAlphaValue) : 0; chGreen = ((rtColor->rgbtGreen - (255 - chAlphaValue)) * 255 / chAlphaValue) >= 0 ? ((rtColor->rgbtGreen - (255 - chAlphaValue)) * 255 / chAlphaValue) : 0; chBlue = ((rtColor->rgbtBlue - (255 - chAlphaValue)) * 255 / chAlphaValue) >= 0 ? ((rtColor->rgbtBlue - (255 - chAlphaValue)) * 255 / chAlphaValue) : 0; } else { chRed = rtColor->rgbtRed; chGreen = rtColor->rgbtGreen; chBlue = rtColor->rgbtBlue; // chAlphaValue = 0; } BUFFER->Write(&chBlue, 1); BUFFER->Write(&chGreen, 1); BUFFER->Write(&chRed, 1); BUFFER->Write(&chAlphaValue, 1); rtColor ++; rtAlphaColor ++; } } BUFFER->SaveToFile(stFilename); } //--------------------------------------------------------------------------- namespace Alphaimage { void __fastcall PACKAGE Register() { TComponentClass classes[1] = {__classid(TAlphaImage)}; RegisterComponents("Nine", classes, 0); } } //---------------------------------------------------------------------------