• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

用Delphi直接获取bmp图片的像素

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
function getImagePixels(f: string): Integer;
var
  jpg: TJpegImage;
  bmp: TBitmap;
begin
  Result := 0;
  if not FileExists(f) then
    Exit;

  if SameText(ExtractFileExt(f), '.bmp') then
  begin
    bmp := TBitmap.Create;
    try
      bmp.LoadFromFile(f);
      Result := bmp.Width * bmp.Height;
    finally
      FreeAndNil(bmp);
    end;
  end
  else if SameText(ExtractFileExt(f), '.jpg') then
  begin
    jpg := TJpegImage.Create;
    try
      jpg.LoadFromFile(f);
      Result := jpg.Width * jpg.Height;
    finally
      FreeAndNil(jpg);
    end;
  end;
end;

////////////////////////////////////////////

 

 

用Delphi改变图片的像素,即大小

用Delphi改变图片的像素,即大小.需代码!急用,谢谢!

我给你讲一种非常简单的方法:

第一步:在窗体上放上image1和image2两个图片控件。再放一个Button按钮控件。

第二步:在image1的Picture属性中载入一张JPG或者BMP图片。而image2不要管它。

第三步:双击Button进行按扭编写环境。写入下面代码:

Image2.Height := 200;//新图像高度
Image2.Width := 300;//新图像宽度
Image2.Canvas.StretchDraw(Image2.ClientRect,Image1.Picture.Graphic);
Image2.Picture.SaveToFile('c:/b.jpg');//保存新图像



问题回答完了,请测试无误后立即给分,别拖时间。

你没有说要压缩,所以我没写压缩的代码。其实这种情况最好是要压缩一下,压缩代码也非常简单(因为我不喜欢太长的代码),如果你需要请加我QQ5555044

晕。。。。。。。。不知道。。。。。。


uses添加Jpeg.

var
bmp,bmp1:TBitmap;
jpeg:TJpegImage;
str:string;
begin
str:='你的图片的完整路径+图片名'
if (ExtractFileExt(str)='.JPG') or (ExtractFileExt(str)='.jpg') then
begin
jpeg:=TJpegImage.Create;
try
jpeg.LoadFromFile(str);
bmp:=TBitmap.Create;
try
bmp.Width:=strtoint(edit1.Text);
bmp.Height:=strtoint(edit2.Text);
bmp.Canvas.StretchDraw(rect(0,0,bmp.Width,bmp.Height),jpeg);
jpeg.Assign(bmp);
finally
bmp.Free;
end;
jpeg.SaveToFile('D:/aa.jpg');
finally
jpeg.Free;
end;
end;
end;
if (ExtractFileExt(str)='.BMP') or (ExtractFileExt(str)='.bmp') then
begin
bmp1:=TBitmap.Create;
try
bmp1.LoadFromFile(str);
bmp:=Tbitmap.Create;
try
bmp.Width:=strtoint(edit1.Text);
bmp.Height:=strtoint(edit2.Text);
bmp.Canvas.StretchDraw(rect(0,0,bmp.Width,bmp.Height),bmp1);
bmp1.Assign(bmp);
finally
bmp.Free;
bmp1.SaveToFile('D:/aa.bmp');
end;
finally
bmp1.Free;
end;
end;
end;

只是edit1和edit2中添加的bmp的宽和高不要太大了,否则会出现“储存空间不足”错误。具体多大数值就超出了,具体情况具体分析,你可以自己试一下。 

///////////////////////////////////////

 

 

delphi 取图片宽高

Var   
      Bmp:TBitMap;   
      Stream:TMemoryStream;   
  begin   
      Bmp   :=TBitMap.Create;   
      Bmp.LoadFromFile('XX.BMP');   
  //尺寸   
      PX   :=Bmp.Width   ;   
      PY   :=Bmp.Height;   
      Stream:=TMemoryStream.Create;   
      Bmp.SaveToStream(Stream);   
  //大小   
      Size   :=Stream.Size;   
      Stream.Free;   
      Bmp.Free;   
  end;   

可以用TBITMAP得到BMP文件   
  TICON得到ICO文件   
  TJPGIMAGE得到JPEG,JPG文件,DELPHI现只支持这些格式,如要用其它的,呵呵,你自己作解码算法吧,就没这么简单了

//////////////////////////////////////////////////

 

通过QQ截图来的图片 在delphi做的程序中按一下按钮把图片显示在image控件上
procedure TForm1.Button1Click(Sender: TObject);
var
    i:integer;
    FIsBitmap:boolean;
begin
    FIsBitmap:=false;
    for   i:=0   to   clipboard.FormatCount   -1   do   //检测ClipBoard中是否有位图
        if   Clipboard.Formats[i]=2   then
        begin
            FIsBitmap:=true;
            break;
        end;
    if  FIsBitmap then
      Image1.Picture.LoadFromClipBoardFormat(cf_BitMap,ClipBoard.GetAsHandle(cf_Bitmap),0)
    else
      Showmessage('剪贴板中没有图片!');
end;

////////////////////////////////////////////////////////////////

DELPHI图像处理研究3 -- 快速判断JPG大小

Jpeg图像是应用最为广泛的图像格式之一。Borland已经为JPG进行了封装,只要在uses语句中加入jpeg单元,就可以直接用TImage解读Jpeg文件了。

对于TJpegImage类,相对比较简单。说些特殊的处理吧。

数码照片一般都很大,现在千万像素级的照片,读取JPG的时间会很长。TJpegImage有一个Scale属性,在解读JPEG图像之前,先设置Scale,就可以快速解读。读取的速度可以是完全解读时的4倍、8倍,当然解读的图像内容也只有整图的1/4或1/8的大小。但如果我们解读了照片以后只是显示在屏幕上,往往不需要读取整图,也许1/8的大小已经足够显示了。

问题是,如何事先知道Jpeg图像的长和宽的尺寸呢?只有事先知道照片的大小,才能知道应该设置多少的Scale,才可能有效地缩小读取图像。这里有个函数可以快速得到JPG的长和宽,通过读取JPG的头信息从而知道图像大小,而不需要解读整个图像。

procedure GetJPGSize(const sFile: string; var wWidth, wHeight: word);
const
  ValidSig : array[0..1] of byte = ($FF, $D8);
  Parameterless = [$01, $D0, $D1, $D2, $D3, $D4, $D5, $D6, $D7];
var
  Sig: array[0..1] of byte;
  f: TFileStream;
  x: integer;
  Seg: byte;
  Dummy: array[0..15] of byte;
  Len: word;
  ReadLen: LongInt;
begin
  FillChar(Sig, SizeOf(Sig), #0);
  f := TFileStream.Create(sFile, fmOpenRead);
  try
    ReadLen := f.Read(Sig[0], SizeOf(Sig));

    for x := Low(Sig) to High(Sig) do
      if Sig[x] <> ValidSig[x] then ReadLen := 0;

    if ReadLen > 0 then
    begin
      ReadLen := f.Read(Seg, 1);
      while (Seg = $FF) and (ReadLen > 0) do
      begin
        ReadLen := f.Read(Seg, 1);
        if Seg <> $FF then
        begin
          if (Seg = $C0) or (Seg = $C1) then
          begin
            ReadLen := f.Read(Dummy[0], 3); { don't need these bytes }
            wHeight := ReadMWord(f);
            wWidth := ReadMWord(f);
          end else begin
            if not (Seg in Parameterless) then
            begin
              Len := ReadMWord(f);
              f.Seek(Len-2, 1);
              f.Read(Seg, 1);
            end else
              Seg := $FF;
          end;
        end;
      end;
    end;
  finally
    f.Free;
  end;
end;

在wWidth, wHeight中将返回JPG文件的长宽。这样,我们在显示JPG照片的时候,可以先通过GetJPGSize得到照片的长和宽,然后根据将要显示的屏幕大小,有效设置TJpegImage的Scale属性,快速显示Jpg图像。 
////////////////////////////////////////////////////////////

 

DELPHI图像处理研究2 -- 遍历像素的方法

作者:zjda07 日期:2009-02-04

字体大小:   

 

我逐步写一些图像处理方面的经验作为技术研究或讨论吧。

DELPHI中,所有的图像需要对图像的内容进行处理之前,都应该先转换成TBitmap类。除非只是简单地显示一下图像,或者事先已经有类把相应的功能进行打包。

TBitmap类是DELPHI已经封装好的,访问的速度也相当快。处理前一般把BMP转换成24位的图像深度
PixelFormat := pf24bit;
这么做的好处是,此后的代码处理比较简单化了,可以避免由于颜色深度不同而引起的错位或内容错乱等莫名其妙的问题。

接下来说一下如何访问图像的内容。请耐心看,可能要看好几篇这系列的文章才能开始真正地编写程序。

访问图像的内容,可以直接利用bmp的画面属性Canvas。Canvas是由一个一个像素组成的,可以直接引用这些像素,就可以获得这些点的颜色值。例如左上角的第一个点是
bmp.Canvas.Pixels[0, 0];
它的值是TColor。我写了一个函数可以直接把TColor中R(红)、G(绿)、B(蓝)三个分量的值分离出来:
procedure GetRGBFromColor(color: TColor; var r, g, b: Integer);
begin
  r := color and $000000FF;
  g := (color shr 8) and $000000FF;
  b := (color shr 16) and $000000FF;
end;

用Pixels去访问bmp是最基本的,也是最直接最简单的,只要给出坐标值就可以获利颜色。但这种方法的缺点是,运算的速度比较慢。如果我们要对整张照片的所有像素值都进行遍历和读取,速度是极慢的。

接下来介绍bmp访问中最常用的方法吧。为了克服pixels访问太慢的问题,Borland为TBitmap增加了一个Scanline的方法,利用它可以快速定位图像的某一行,利用指针的移动对图像内容进行读写。可以说,绝大部分图像处理代码,都是利用这各方法进行访问的。

在使用Scanline之前,请在代码最前面interface加入以下代码
interface
{$DEFINE USE_SCANLINE}

让我们用一个令图像内容变成灰度图的代码例子看一下scanline的使用吧
procedure GrayScale(var clip: tbitmap);
var
  p0:pbytearray;
  Gray,x,y: Integer;
begin
  for y:=0 to clip.Height-1 do
  begin
    p0:=clip.scanline[y];
    for x:=0 to clip.Width-1 do
    begin
      Gray:= Round(p0[x*3] * 0.3 + p0[x*3 + 1] * 0.59 + p0[x*3 + 2] * 0.11);
      p0[x*3]:=Gray;
      p0[x*3+1]:=Gray;
      p0[x*3+2]:=Gray;
    end;
  end;
end;

p0是一个指针,y值是需要读取的图像的行数,p0:=clip.scanline[y]即表示读取第y行的内容。
x是表示列数,p0[x*3]、p0[x*3+1]、p0[x*3+2]分别表示第x列的像素的BGR三个分量的值。只要直接修改p0[x*3]、p0[x*3+1]、p0[x*3+2],就可以让图像内容发生改变。
上面的函数中,我们先读取了某一个点的红绿蓝的值,然后进行运算得到一个灰度值,再把灰度值赋给红绿蓝分量。当某一个点的RGB三值相同时,这个点显示的颜色就是灰色的了。

可以有人对Gray的运算有疑问,后面的三个系数是如何得到的,这很简单,我们可以修改这三个系数为其他值的,只不过根据大部分人的经验,当三个系数为这样取值时,彩色转换为灰度得到的效果最接近人类的视觉感受而已。

这里对Gray的输出还少了一步溢出值的检验,凡是赋给RGB的值,必须是0-255之间的(不难理解,RGB各点8位,共24位。8位的最大值是255)。 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap