• (转)彩图变灰度图


    将一幅图片转化成灰度图,具体来说应该分为以下几步:
    1.提取图片的每一个象素的值,然后建立三个数据表,1->G 2->R 3->B.
    2.为每一种颜色值建立一附图.
    方法如下:
        若源图一点为 (R100,G200,B210),这相应的三附图的点颜色为1_(100,100,100), 2_(200,200,200),3_(210,210,210).
    3. 你说希望寻求一种高效率的方法,但我个人认为什么方法可能都需要提取图片的每一个象素,你也不可能只是要将一幅图片转化成灰度图(否则这可用专门的software),往后来还是要知道每一个象素的数据.我做过这个程序,速度还可以(在386上).


    上面是基于图片在屏幕上的方法,如果你的图片是文件就简单多了,在读文件时只分别读RGB,再写屏就可以了.



    改palette最快, 灰度只有256阶, 用256色位图, 改掉palette就改变全图了.(只要循环256次).

    你看这样行不行,速度比不上Another_eYes的方法快.但可以满足我的要求.



    type
      TFColor  = record
                  b,g,r:Byte
                 end;
     
      PFColor  =^TFColor;

    procedure Gray(srcBmp,DstBmp:TBitMap);
    var
      x,y:                      Integer;
      Gr:                       Byte;
      incRow,Gap:               integer;
      DstTmp,SrcTmp:            PFColor;
      SrcBmInfo,DstBmInfo:      TBitmapInfo;
      SrcBmHeader,DstBmHeader:  TBitmapInfoHeader;
      width,height,Size:        integer;
      SrcBits,DstBits:          pointer;
      mDC:                      Integer;
    begin
      Width:=SrcBmp.Width;
      Height:=SrcBmp.Height;
      Size:=((Width*3)+(Width mod 4))*Height;
      incRow:=((Width*3)+(Width mod 4));
      Gap:=Width mod 4;
      DstBmp.Assign(SrcBmp);//这句可要可不要,看情况定
      getMem(srcBits,size);
      getMem(DstBits,size);
      with SrcbmHeader do begin
        biSize:=SizeOf(SrcbmHeader);
        biWidth:=Width;
        biHeight:=-Height;
        biPlanes:=1;
        biBitCount:=24;
        biCompression:=BI_RGB;
      end;
      SrcbmInfo.bmiHeader:=srcbmHeader;

      with DstbmHeader do begin
        biSize:=SizeOf(DstbmHeader);
        biWidth:=Width;
        biHeight:=-Height;
        biPlanes:=1;
        biBitCount:=24;
        biCompression:=BI_RGB;
      end;
      DstbmInfo.bmiHeader:=DstbmHeader;

      try
        mDC:=GetDC(0);
        GetDIBits(mDC,srcBmp.Handle,0,Height,srcBits,srcbmInfo,DIB_RGB_COLORS);

        DstTmp:=DstBits;
        for y:=0 to Height-1 do begin
          for x:=0 to Width-1 do begin
            SrcTmp:=pointer(integer(SrcBits)+(y*IncRow+x*3));
            Gr := HiByte(SrcTmp^.r * 77 + SrcTmp^.g * 151 + SrcTmp^.b * 28);
            DstTmp^.r:=Gr;
            DstTmp^.g:=Gr;
            DstTmp^.b:=Gr;
            Inc(DstTmp);
          end;
          DstTmp:=Pointer(Integer(DstTmp)+Gap);
        end;
        SetDIBits(mDC,DstBmp.Handle,0,Height,DstBits,DstbmInfo,DIB_RGB_COLORS);
        ReleaseDC(0,mDC);
      finally
        freemem(SrcBits);
        freemem(DstBits);
      end;
    end;

    其中GetDIBBits和SetDIBBits函数可以看API帮助.这个方法与显存有关,
    如果你的显存不够大,大图象就处理不,600X600的图象需要
    600x600x3=1080000Bytes的显存.

    DIB不是device independant bitmap吗?
    和设备无关的, 在内存中.
    DDB才和显存有关.
    不用palette的话:
    onedolphi的程序稍微修改了一下:
    procedure Gray(bmp: TBitmap);
    var
      p: PByteArray;
      w: Integer;
      i, j: Integer;
    begin
      bmp.pixelformat := pf24bit;
      for i := 0 to bmp.height - 1 do
      begin
        p := bmp.scanline[i];
        j := 0;
        while j < (bmp.width-1) * 3 do
        begin
          w :=(p[j] * 28 + p[j+1] * 151 + p[j+2]*77);
          w := w shr 8;
          p[j] := byte(w);
          p[j+1] := byte(w);
          p[j+2] := byte(w);
     end;

    end;

    end;

  • 相关阅读:
    Flask把变量注册到模板中
    $.each与$(data).each区别
    【Python备忘】python判断文件和文件夹是否存在
    ISP图像质量自动化测试方法
    使用微软的(how-old.net)构建智能门店管理系统
    在virtualenv中安装libxml2和libxslt
    Python 装饰器学习以及实际使用场景实践
    tensorflow零起点快速入门(4) --入门常用API
    tensorflow零起点快速入门(3)
    树莓派和STM32通过USB和串口通信记录
  • 原文地址:https://www.cnblogs.com/huking/p/1706786.html
Copyright © 2020-2023  润新知