C++Builder 程序员博客
3 Aug
我现在已经实现了将选中的彩色jpg图片在TImage中显示,请问如何将选中的彩色jpg图片转换成灰阶图片并在TImage中显示?急盼各位高手的回复!先谢了!
以上是Bitmap格式,你可先将JPG转成Bitmap再调用函数
//————————————————————————— #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include <jpeg.hpp> //————————————————————————— #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //————————————————————————— __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Graphics::TBitmap *bmp = new Graphics::TBitmap(); TJPEGImage *jpg = new TJPEGImage(); try { jpg->LoadFromFile("D:\\VclLib\\GdiplusDemo\\Media\\100_0349.jpg"); bmp->Assign(jpg); bmp->PixelFormat = pf24bit; BYTE *p = (BYTE*)bmp->ScanLine[bmp->Height - 1]; int off = (((24 * bmp->Width + 31) & 0xffffffe0) >> 3) - bmp->Width * 3; for (int y = 0; y < bmp->Height; y ++, p += off) { for (int x = 0; x < bmp->Width; x ++) { int v = (117 * p[0] + 601 * p[1] + 306 * p[2] + 512) >> 10; *p ++ = v; *p ++ = v; *p ++ = v; } } // bmp->SaveToFile("d:\\tmp.bmp"); Image1->Picture->Assign(bmp); } __finally { delete jpg; delete bmp; } } //—————————————————————————
private: // User declarations void __fastcall GrayIt(Graphics::TBitmap *bmp); //————————————————————————— void __fastcall TForm1::GrayIt(Graphics::TBitmap * bmp) { BYTE * ptr; int Gray; bmp->PixelFormat=pf24bit; for(int y = 0; y<bmp->Height;y++) { ptr=(BYTE*)bmp->ScanLine[y]; for(int x=0;x<bmp->Width*3;x+=3) { Gray=299*ptr[x+2]+587*ptr[x+1]+114*ptr[x]; ptr[x]=Gray/1000; ptr[x+1]=Gray/1000; ptr[x+2]=Gray/1000; } } } //————————————————————————— void __fastcall TForm1::Button1Click(TObject *Sender) { Graphics::TBitmap *bmp=new Graphics::TBitmap; bmp->Assign(Image1->Picture->Graphic); GrayIt(bmp); Image1->Picture->Assign(bmp); delete bmp; } //—————————————————————————
//—————————————————————————
#include <vcl.h>//试例原码
#pragma hdrstop
#include "Unit1.h"
#include "math.h"
#include <printers.hpp>
//—————————————————————————
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//—————————————————————————
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//—————————————————————————
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Scale->ItemIndex = 0;
PixelFormat->ItemIndex = 0;
ColorSpace->ItemIndex = 0;
Performance->ItemIndex = 0;
OpenDialog1->Filter = GraphicFilter(__classid(TGraphic));
FileListBox1->Mask = GraphicFileMask(__classid(TGraphic));
}
//—————————————————————————
void __fastcall TForm1::FileListBox1Click(TObject *Sender)
{
Image1->Picture->LoadFromFile(FileListBox1->FileName);
SetJPEGOptions(this);
}
//—————————————————————————
void __fastcall TForm1::Exit1Click(TObject *Sender)
{
Close();
}
//—————————————————————————
void __fastcall TForm1::Open1Click(TObject *Sender)
{
if (OpenDialog1->Execute()){
Image1->Picture->LoadFromFile(OpenDialog1->FileName);
SetJPEGOptions(this);
}
}
//—————————————————————————
void __fastcall TForm1::SetJPEGOptions(TObject *Sender)
{
bool isJpg;
isJpg = (Image1->Picture->Graphic->ClassNameIs("TJPEGImage"));
TJPEGImage *Jpeg;
if (isJpg){
Jpeg=(TJPEGImage *)Image1->Picture->Graphic;
Jpeg->PixelFormat = TJPEGPixelFormat(PixelFormat->ItemIndex);//位
Jpeg->Scale = TJPEGScale(Scale->ItemIndex); //比例
Jpeg->Grayscale = bool(ColorSpace->ItemIndex); //色彩
Jpeg->Performance = TJPEGPerformance(Performance->ItemIndex); //速度
}
Scale->Enabled = isJpg;
PixelFormat->Enabled = isJpg;
ColorSpace->Enabled = isJpg;
Performance->Enabled = isJpg;
}
.h文件
//—————————————————————————
#ifndef Unit1H
#define Unit1H
//—————————————————————————
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <FileCtrl.hpp>
#include <Dialogs.hpp>
#include <Menus.hpp>
#include <jpeg.hpp>
//—————————————————————————
class TForm1 : public TForm
{
__published: // IDE-managed Components
TPanel *Panel3;
TDriveComboBox *DriveComboBox1;
TComboBox *Scale;
TComboBox *PixelFormat;
TComboBox *ColorSpace;
TComboBox *Performance;
TPanel *Panel1;
TDirectoryListBox *DirectoryListBox1;
TFileListBox *FileListBox1;
TScrollBox *ScrollBox1;
TImage *Image1;
TMainMenu *MainMenu1;
TMenuItem *File1;
TMenuItem *Open1;
TMenuItem *N2;
TMenuItem *Exit1;
TOpenDialog *OpenDialog1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall FileListBox1Click(TObject *Sender);
void __fastcall Exit1Click(TObject *Sender);
void __fastcall Open1Click(TObject *Sender);
void __fastcall SetJPEGOptions(TObject *Sender);
private:
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//—————————————————————————
extern PACKAGE TForm1 *Form1;
//—————————————————————————
#endif
我是个新手,第一次发帖子,没想到一天时间就有这么多热心的人提供帮助,我真是太感动了!
这些Code我先回去试试,稍后再告诉大家问题是否得到了解决。谢谢了!
其实,你也可以直接算出灰度,用三元色相加再除三,就是灰度值
下面是核心语句
void __fastcall TMainForm::BitBtn1Click(TObject *Sender)
{
Image->Picture->Bitmap->PixelFormat = pf4bit;
}
我用maozefa的算法实现了图片转成灰阶,但是算法我还是看不懂,能否可以请maozefa帮忙解释一下?谢谢!
RGB颜色转灰度的经典公式是:
nGray=0.299*R+0.587*G+0.114*B
因为同样的单色G=255和B=255其亮度其实并不一样,所以(R+G+B)/3的方法不太准确.
maozefa的算法效率比较高,公式是一样的.
正如楼上说的,我的算法0.299*R+0.587*G+0.114*B,不过扩大了1024倍,转换为整数处理,最后右移10也就是除以1024还原。
获益不浅,非常感谢!