图像问题 请问如何把 真彩图像 分别转为 256色索引图 和 灰度图

XWGer 2006-01-08 11:32:08
如题,分不够再加 谢谢大家
...全文
377 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
constantine 2006-01-09
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/4476/4476125.xml?temp=.2957575
看看这个帖子

#pragma hdrstop

#include <vcl.h>
#include <windows.h>
#include "dither.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

LColor ColorCount[4096]; //为记录颜色使用频率的数组
BYTE ColorTable[4096]; // 为记录颜色索引值的数组

//---------------------------------------------------------------------------
//统计颜色使用频率
void CountColor(Graphics::TBitmap *BitMap,LColor * ClrCount)
{
PRGBColor Ptr;
int i, j;
int CIndex;
for(i=0;i<4096;i++) // 初始化ColorCount数组
{
ClrCount[i].Color = i;
ClrCount[i].Times = 0;
}

for(i=0;i<BitMap->Height;i++)
{
Ptr = (TRGBColor*)BitMap->ScanLine[i];
for(j=0;j<BitMap->Width;j++)
{ //取 R、G、B三种颜色的前4位组成12位,共4096种颜色
CIndex = (Ptr->R & 0xF0)<<4;
CIndex = CIndex + (Ptr->G & 0xF0);
CIndex = CIndex + ((Ptr->B & 0xF0)>>4);
ClrCount[CIndex].Times++; //计算颜色的使用次数
Ptr++;
}
}
}
//---------------------------------------------------------------------------
// 清除使用次数为 0 的颜色数据,返回值为当前图像中颜色的种类
int Delzero(LColor *ClrCount)
{
int i,CIndex=0;
for(i=0;i<4096;i++)
{
if(ClrCount[i].Times)
{
ClrCount[CIndex].Color = ClrCount[i].Color;
ClrCount[CIndex].Times = ClrCount[i].Times;
ClrCount[i].Times = 0;
CIndex++;
}
}
return CIndex;
}
//---------------------------------------------------------------------------
// 快速排序, 将各种颜色 按使用的频率排序(Hight -- Low )
void QuickSort(LColor *A,int iLo,int iHi)
{
int Lo, Hi, Mid;
LColor Temp;
Lo = iLo;
Hi = iHi;
Mid = A[(Lo+Hi)/2].Times;
do
{
while(A[Lo].Times>Mid) Lo++;
while(A[Hi].Times<Mid) Hi--;
if(Lo <= Hi)
{
Temp.Color = A[Lo].Color;
Temp.Times = A[Lo].Times;
A[Lo].Color = A[Hi].Color;
A[Lo].Times = A[Hi].Times;
A[Hi].Color = Temp.Color;
A[Hi].Times = Temp.Times;
Lo++;
Hi--;
}
}while(Hi > Lo);
if(Hi>iLo) QuickSort(A, iLo, Hi);
if(Lo<iHi) QuickSort(A, Lo, iHi);
}
//---------------------------------------------------------------------------
void Sort(LColor *A,int Top)
{
QuickSort(A, 0, Top);
}
//---------------------------------------------------------------------------
// 构建调色表
HPALETTE BuildColorTable(LColor *ClrCount,PLogPalette Pal)
{
int i;
Pal->palVersion = 0x300;
Pal->palNumEntries = 256;
for(i=0;i<=255;i++)
{
Pal->palPalEntry[i].peRed = ((ClrCount[i].Color & 0xF00)>>4) + 7;
Pal->palPalEntry[i].peGreen = (ClrCount[i].Color & 0xF0) + 7;
Pal->palPalEntry[i].peBlue = ((ClrCount[i].Color & 0xF)<<4) + 7;
Pal->palPalEntry[i].peFlags = 0;
}
return CreatePalette(Pal);
}
//---------------------------------------------------------------------------
//根据统计的信息调整图像中的颜色, 将不常用的颜色用常用的颜色代替
void AdjustColor(int ClrNumber,LColor *ClrCount)
{
int i,C,Error,m,iTmp;
BYTE CIndex;
// for i := 0 to 4096 do ColorTable[i] := 0;
for(i=0;i<=255;i++)
ColorTable[ClrCount[i].Color] = i;

for(i=256;i<ClrNumber;i++)
{
Error=10000; //求最小误差
CIndex=0;
C=ClrCount[i].Color;
//从256个颜色索引值中取最接近的值替代
for(m=0;m<=255;m++)
{
iTmp = abs(ClrCount[m].Color) - C;
if(iTmp < Error)
{
Error = iTmp;
CIndex = m;
}
}
ColorTable[ClrCount[i].Color] = CIndex;
}
}
//---------------------------------------------------------------------------
void __fastcall Trueto256(Graphics::TBitmap *SBitMap,Graphics::TBitmap *DBitMap)
{
PLogPalette Pal;
int i, j, t, ColorNumber;
PRGBColor SPtr;
BYTE *DPtr;
if(SBitMap->Empty)
return;

CountColor(SBitMap, ColorCount); //统计颜色的使用频率
ColorNumber = Delzero(ColorCount); //去处不使用的颜色
Sort(ColorCount, ColorNumber); // 将颜色按使用频率排序
AdjustColor(ColorNumber, ColorCount);

//with DBitMap do
DBitMap->PixelFormat = pf8bit;
SBitMap->PixelFormat = pf24bit;
DBitMap->Width = SBitMap->Width;
DBitMap->Height = SBitMap->Height;

Pal = (PLogPalette)malloc(sizeof(TLogPalette)+sizeof(TPaletteEntry)*255);
BuildColorTable(ColorCount, Pal);
DBitMap->Palette = BuildColorTable(ColorCount, Pal); // Set DBitMap.Palette
free(Pal);

for(i=0;i<DBitMap->Height;i++)
{
SPtr = (PRGBColor)SBitMap->ScanLine[i];
DPtr = (BYTE *)DBitMap->ScanLine[i];
for(j=0;j<DBitMap->Width;j++)
{
t = (SPtr->R & 0xF0)<<4;
t = t + (SPtr->G & 0xF0);
t = t + ((SPtr->B & 0xF0)>>4);
*DPtr = ColorTable[t];
SPtr++;
DPtr++;
}
}
}
//---------------------------------------------------------------------------


头文件 dither.h
//---------------------------------------------------------------------------

#ifndef ditherH
#define ditherH
//---------------------------------------------------------------------------
struct TRGBColor;
typedef TRGBColor *PRGBColor;

#pragma pack(push, 1)
struct TRGBColor
{
BYTE B;
BYTE G;
BYTE R;
} ;
#pragma pack(pop)

typedef BYTE *PByte;

#pragma pack(push, 4)
struct LColor
{
int Color;
int Times;
} ;
#pragma pack(pop)

//-- var, const, procedure ---------------------------------------------------
void __fastcall Trueto256(Graphics::TBitmap* SBitmap, Graphics::TBitmap* DBitMap);
#endif

cczlp 2006-01-09
  • 打赏
  • 举报
回复
灰度
typedef struct {
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY dummy[256];
} LOGPAL;
LOGPAL GrayPal;
int i;

Image1->Picture->LoadFromFile("c:\\aa.bmp");

GrayPal.palVersion=0x300;
GrayPal.palNumEntries=256;
for(i=0;i<256;i++)
{
GrayPal.dummy[i].peRed=i;
GrayPal.dummy[i].peGreen=i;
GrayPal.dummy[i].peBlue=i;
GrayPal.dummy[i].peFlags=0;
}
Image1->Picture->Bitmap->PixelFormat=pf8bit;
Image1->Picture->Bitmap->Palette= CreatePalette((const tagLOGPALETTE *)&GrayPal);
jixingzhong 2006-01-09
  • 打赏
  • 举报
回复
真彩图像 分别转为 256色索引图 和 灰度图
------------------
要转换为 灰度图,
好像要一个 象素颜色转换 公式的,
不过具体忘了 ....

读取象素的颜色值,
然后计算灰度,
就 OK 了 ...
LLBer 2006-01-09
  • 打赏
  • 举报
回复
厉害啊!我问一句,怎么调用这个函数呢?比如我现在有一幅图 (aa.bmp)想把他转成256的,怎么搞
麻酱面条 2006-01-08
  • 打赏
  • 举报
回复
这方面的东西应该不少,用 google 搜索一下哈
icwin 2006-01-08
  • 打赏
  • 举报
回复
up

13,871

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧