如题,我根据资料写出的程序如下,自己加了trackbar调整,但拖动滑块时容易把图像调花,怎么才能平滑调整呢?请高手指点。代码如下:procedure HSLtoRGB(H, S, L: Integer; var R, G, B: Integer);
//hsl颜色空间到rgb空间的转换
var //类似于返回多个值的函数
   Sat, Lum: Double;
begin
   R := 0;
   G := 0;
   B := 0;
   if (H < 360) and (H >= 0) and (S <= 100) and (S >= 0) and (L <= 100) and (L
      >=
      0) then
      begin
         if H <= 60 then
            begin
               R := 255;
               G := Round((255 / 60) * H);
               B := 0;
            end
         else if H <= 120 then
            begin
               R := Round(255 - (255 / 60) * (H - 60));
               G := 255;
               B := 0;
            end
         else if H <= 180 then
            begin
               R := 0;
               G := 255;
               B := Round((255 / 60) * (H - 120));
            end
         else if H <= 240 then
            begin
               R := 0;
               G := Round(255 - (255 / 60) * (H - 180));
               B := 255;
            end
         else if H <= 300 then
            begin
               R := Round((255 / 60) * (H - 240));
               G := 0;
               B := 255;
            end
         else if H < 360 then
            begin
               R := 255;
               G := 0;
               B := Round(255 - (255 / 60) * (H - 300));
            end;         Sat := Abs((S - 100) / 100);
         R := Round(R - ((R - 128) * Sat));
         G := Round(G - ((G - 128) * Sat));
         B := Round(B - ((B - 128) * Sat));         Lum := (L - 50) / 50;
         if Lum > 0 then
            begin
               R := Round(R + ((255 - R) * Lum));
               G := Round(G + ((255 - G) * Lum));
               B := Round(B + ((255 - B) * Lum));
            end
         else if Lum < 0 then
            begin
               R := Round(R + (R * Lum));
               G := Round(G + (G * Lum));
               B := Round(B + (B * Lum));
            end;
      end;
end;procedure RGBtoHSL(R, G, B: Integer; var H, S, L: Integer);
// RGB空间到HSL空间的转换
var
   Delta: Double;
   CMax, CMin: Double;
   Red, Green, Blue, Hue, Sat, Lum: Double;
begin
   Red := R / 255;
   Green := G / 255;
   Blue := B / 255;
   CMax := Max(Red, Max(Green, Blue));
   CMin := Min(Red, Min(Green, Blue));
   Lum := (CMax + CMin) / 2;
   if CMax = CMin then
      begin
         Sat := 0;
         Hue := 0;
      end
   else
      begin
         if Lum < 0.5 then
            Sat := (CMax - CMin) / (CMax + CMin)
         else
            Sat := (cmax - cmin) / (2 - cmax - cmin);
         delta := CMax - CMin;
         if Red = CMax then
            Hue := (Green - Blue) / Delta
         else if Green = CMax then
            Hue := 2 + (Blue - Red) / Delta
         else
            Hue := 4.0 + (Red - Green) / Delta;
         Hue := Hue / 6;
         if Hue < 0 then
            Hue := Hue + 1;
      end;
   H := Round(Hue * 360);
   S := Round(Sat * 100);
   L := Round(Lum * 100);
end;
//亮度调节
procedure TFormMain.TrackBarBrightnessChange(Sender: TObject);
var
   bmp: TBITMAP;
   x, y, ScanlineBytes,i,DeltaP: integer;
   p: prgbtriplearray;
   RVALUE, bvalue, gvalue: integer;
   hVALUE, sVALUE, lVALUE: integer;
begin
   self.DoubleBuffered := true;
   //设置双缓冲
   if imgCarPhoto.Picture.Graphic <> nil then
   else
   begin
      TrackBarBrightness.Position:=50;
      OriginalBrightnessPosition:=TrackBarBrightness.Position;
      Label6.Caption:='亮度 ' + IntToStr(OriginalBrightnessPosition);
      exit;
   end;   bmp := TBITMAP.Create;
   bmp.Assign(imgCarPhoto.Picture.Bitmap);
   //加载位图
   bmp.PixelFormat := pf24bit;
   //指定为24位
   p := bmp.ScanLine[0];
   ScanlineBytes := integer(bmp.ScanLine[1]) - integer(bmp.ScanLine[0]);
   //获取两行间距,此法只需执行Scanline两次,速度快,是优化的   i:=TrackBarBrightness.Position;
   DeltaP:=i - OriginalBrightnessPosition;
   OriginalBrightnessPosition:=i;
   Label6.Caption:='亮度 ' + IntToStr(i);   for y := 0 to bmp.Height - 1 do
      begin
         for x := 0 to bmp.Width - 1 do
            begin
               //获取RGB的三个分量值,并进行赋值
               RVALUE := p[x].rgbtRed;
               gVALUE := p[x].rgbtGreen;
               bVALUE := p[x].rgbtBlue;
               // 调用前面的RGB转HSL过程,获取HSL三个分量值
               RGBtoHSL(RVALUE, gVALUE, bVALUE, hVALUE, sVALUE, lVALUE);
               //饱和度值进行线性调节。
               lVALUE := lVALUE + DeltaP;
               lVALUE := min(100, lVALUE);
               lVALUE := max(0, lVALUE);
               //下面两行是饱和度度减小操作
               //SVALUE := SVALUE - 5;
               //调用前面的HSL空间转RGB颜色空间的过程,获得RGB三个分量
               HSLtorgb(hVALUE, sVALUE, lVALUE, rVALUE, gVALUE, bVALUE);
               p[x].rgbtRed := RVALUE;
               p[x].rgbtGreen := gVALUE;
               p[x].rgbtBlue := bVALUE;
            end;
         inc(integer(p), ScanlineBytes)   //指针递增
      end;
   imgCarPhoto.Picture.Bitmap.Assign(bmp);
   Bmp.Free;
end;
//对比度调节
procedure TFormMain.TrackBarContrastChange(Sender: TObject);
var
    p: PByteArray;
    x, y, i, DeltaP: Integer;
    Bmp: TBitmap;
begin
    self.DoubleBuffered := true;
    //设置双缓冲
    if imgCarPhoto.Picture.Graphic <> nil then
    else
    begin
      TrackBarContrast.Position:=128;
      OriginalContrastPosition:=TrackBarContrast.Position;
      Label5.Caption:='对比度 ' + IntToStr(OriginalContrastPosition);
      exit;
    end;    Bmp := TBitmap.Create;
    Bmp.Assign(ImgCarPhoto.Picture.Bitmap);
    Bmp.PixelFormat := pf24Bit;    i:=TrackBarContrast.Position;
    DeltaP:=i - OriginalContrastPosition;
    OriginalContrastPosition:=i;
    Label5.Caption:='对比度 ' + IntToStr(i);
    
    for y := 0 to Bmp.Height - 1 do
    begin
        p := Bmp.scanline[y];
        for x := 0 to Bmp.Width - 1 do
        begin
            //确定阀值为128
            if (p[x * 3] < 246) and (p[x * 3] > 128) and (p[x * 3 + 1] >
                128)
                and (p[x * 3 + 1] < 246)
                and (p[x * 3 + 2] > 128) and (p[x * 3 + 2] < 246) then
            begin
                p[x * 3] := Min(246, Max(128, p[x * 3] + DeltaP));
                p[x * 3 + 1] := Min(246, Max(128, p[x * 3 + 1] + DeltaP));
                p[x * 3 + 2] := Min(246, Max(128, p[x * 3 + 2] + DeltaP));
            end;
            if (p[x * 3] > 10) and (p[x * 3] < 128) and (p[x * 3 + 1] >
                10)
                and (p[x *
                3 + 1] < 128)
                and (p[x * 3 + 2] > 10) and (p[x * 3 + 2] < 128) then
            begin
                p[x * 3] := Min(128, Max(10, p[x * 3] - DeltaP));
                p[x * 3 + 1] := Min(128, Max(10, p[x * 3 + 1] - DeltaP));
                p[x * 3 + 2] := Min(128, Max(10, p[x * 3 + 2] - DeltaP));
            end;
        end;
    end;
    ImgCarPhoto.Picture.Bitmap.Assign(Bmp);
    Bmp.Free;
end;

解决方案 »

  1.   

    HSL调整很费时的,应该用线程,在TTrackbar的改变事件中终止旧线程,启动新线程
      

  2.   

    每次调节都调用原图了,调节后再将它赋给ImgCarPhoto,最后再释放。
      

  3.   

    HSL调节曾试过一幅大图,确实速度很慢,不过程序中多调用小图,这个先不考虑,问题是怎么拖着不花,阿发伯既然说了用线程,可我不知道怎么改,您帮我改改吧?谢谢
      

  4.   

    procedure TFormMain.TrackBarContrastChange(Sender: TObject);
    var
        p: PByteArray;
        x, y, i, DeltaP: Integer;
        Bmp: TBitmap;
    begin
        self.DoubleBuffered := true;
        //设置双缓冲
        if imgCarPhoto.Picture.Graphic <> nil then
        else
        begin
          TrackBarContrast.Position:=128;
          OriginalContrastPosition:=TrackBarContrast.Position;
          Label5.Caption:='对比度 ' + IntToStr(OriginalContrastPosition);
          exit;
        end;    Bmp := TBitmap.Create;
        Bmp.Assign(ImgCarPhoto.Picture.Bitmap);
        //这张肯定不是原图
        Bmp.PixelFormat := pf24Bit;    i:=TrackBarContrast.Position;
        DeltaP:=i - OriginalContrastPosition;
        OriginalContrastPosition:=i;
        Label5.Caption:='对比度 ' + IntToStr(i);
        
        for y := 0 to Bmp.Height - 1 do
        begin
            p := Bmp.scanline[y];
            for x := 0 to Bmp.Width - 1 do
            begin
                //确定阀值为128
                if (p[x * 3] < 246) and (p[x * 3] > 128) and (p[x * 3 + 1] >
                    128)
                    and (p[x * 3 + 1] < 246)
                    and (p[x * 3 + 2] > 128) and (p[x * 3 + 2] < 246) then
                begin
                    p[x * 3] := Min(246, Max(128, p[x * 3] + DeltaP));
                    p[x * 3 + 1] := Min(246, Max(128, p[x * 3 + 1] + DeltaP));
                    p[x * 3 + 2] := Min(246, Max(128, p[x * 3 + 2] + DeltaP));
                end;
                if (p[x * 3] > 10) and (p[x * 3] < 128) and (p[x * 3 + 1] >
                    10)
                    and (p[x *
                    3 + 1] < 128)
                    and (p[x * 3 + 2] > 10) and (p[x * 3 + 2] < 128) then
                begin
                    p[x * 3] := Min(128, Max(10, p[x * 3] - DeltaP));
                    p[x * 3 + 1] := Min(128, Max(10, p[x * 3 + 1] - DeltaP));
                    p[x * 3 + 2] := Min(128, Max(10, p[x * 3 + 2] - DeltaP));
                end;
            end;
        end;
        ImgCarPhoto.Picture.Bitmap.Assign(Bmp);
        //你调整之后把结果图覆盖掉了,怎么会是原图!!!
        Bmp.Free;
    end;
    你应该先备份一张原图,然后每次调用时,bmp.assign(原始图)而不是ImgCarPhoto.Picture.Bitmap这个