Pesquisar no conteúdo do

terça-feira, 18 de agosto de 2015

DELPHI - Alterar brilho e contraste de imagem

Retirado de:

Coding Contrast Enhancement in Delphi

Designing the GUI and The Processing Algorithm
To make our contrast enhancement processing, we need to design the graphical user interface (GUI) first. The GUI is similar with our previous brightness modification user interface. The following steps explains how to make it:
  1. Open (or download first) our previous brightness modification project.
  2. Create a new form (File->New->Form).
  3. Change the name property to ContrastForm, change the Caption property to 'Contrast'. Set the FormStyle property to fsMDIChild. Resize the form to fit the main form (parent form).
  4. On the Object Inspector, click on Events tab, and double click in the OnClose event. You'll be directed to the event handler, and assign the Action variable with caFree between begin and end
    1. procedure TContrastForm.FormClose(Sender: TObject;  
    2. var Action: TCloseAction);  
    3. begin  
    4. Action:=caFree;  
    5. end;  
  5. Add two scroll bar components (from the standard component pallet) to the form. Change the Name property to CenterScrollBar and ContrastScrollBar. Set the Minimum property of CenterScrollBar to 0 and the Maximum to 255. Set the minimum property of ContrastScrollBar to -100 and the maximum to 100. Set the position of CenterScrollBar to 127, set the position of ContrastScrollBar to 0.
  6. Place two label components (from the standar component pallet) to the form, set the layout to associate each label to each scroll bar. Change the Label's caption to 'Center' and 'Contrast' accordingly (see Figure 1).
  7. Add two buttons (from standard component pallet), change their caption to OK and Cancel, and set their name to OKButton and CancelButton accordingly.
  8. Save the unit as ContrastUnit (using menu File->Save As).
  9. Go to Project->Options->Form, point to ContrastForm to select, and press the > button, so the ContrastForm will move to Available forms box, then press OK.
Figure 1. Contrast GUI Form

To modify the image, it's common to backup the original image, so we can do a cancel operation after displaying the change on the original image form. To do this, we have to provide TImage object in the form to temporarily store the image. A procedure (SetContrast) to associate the image input to the brightness form is also needed.

  1. Edit the BrightnessForm abstraction to provide TImage (TemporaryImage and OriginalImage) object and the SetBrightness procedure. A boolean flag (Applied) is also needed to mark whether a Cancel or OK button has been pressed. Add ExtCtrls under uses in the Interface section because we're gonna use TImage component. Edit as shown below:
    1. type  
    2. TContrastForm = class(TForm)  
    3. CenterScrollbar: TScrollBar;  
    4. ContrastScrollBar: TScrollBar;  
    5. Label1: TLabel;  
    6. Label2: TLabel;  
    7. OKButton: TButton;  
    8. CancelButton: TButton;  
    9. procedure FormClose(Sender: TObject; var Action: TCloseAction);  
    10. private  
    11. { Private declarations }  
    12. TemporaryImage:TImage;  
    13. OriginalImage:TImage;  
    14. Applied:boolean;  
    15. public  
    16. { Public declarations }  
    17. procedure SetContrast(Image: TImage);  
    18. end;  
  2. Write the SetContrast procedure definition in the implementation section:
    1. procedure TContrastForm.SetContrast(Image: TImage);  
    2. begin  
    3. try  
    4. begin  
    5. TemporaryImage:=Image;  
    6. TemporaryImage.Picture.Bitmap.PixelFormat:=pf24bit;  
    7. OriginalImage:=TImage.Create(self);  
    8. OriginalImage.Picture.Bitmap.Assign(Image.Picture.Bitmap);  
    9. end;  
    10. except  
    11. begin  
    12. Free; //free the contrast form  
    13. ShowMessage('Cannot complete the operation');  
    14. end;  
    15. end;  
    16. end;  
  3. Double click the CenterScrollBar component, the you'll be directed to its event handler, edit as shown below
    1. procedure TContrastForm.CenterScrollbarChange(Sender: TObject);  
    2. var  
    3. i,j:Integer;  
    4. temp:real;  
    5. pixelPointer:PByteArray;  
    6. originalPixelPointer:PByteArray;  
    7. begin  
    8. try  
    9. begin  
    10. if TemporaryImage.Picture.Bitmap.PixelFormat=pf8bit then  
    11. for i:=0 to TemporaryImage.Picture.Height-1 do  
    12. begin  
    13. pixelPointer:=TemporaryImage.Picture.Bitmap.ScanLine[i];  
    14. originalPixelPointer:=OriginalImage.Picture.Bitmap.ScanLine[i];  
    15. for j:=0 to TemporaryImage.Picture.Width-1 do  
    16. begin  
    17. temp:=((originalPixelPointer[j]-CenterScrollBAr.Position)  
    18. *exp(ContrastScrollBar.Position/50))  
    19. + CenterScrollBar.Position;  
    20. if temp<0>255 then temp:=255;  
    21. pixelPointer[j]:=round(temp);  
    22. end;  
    23. end;  
    24. if TemporaryImage.Picture.Bitmap.PixelFormat=pf24bit then  
    25. for i:=0 to TemporaryImage.Picture.Height-1 do  
    26. begin  
    27. pixelPointer:=TemporaryImage.Picture.Bitmap.ScanLine[i];  
    28. originalPixelPointer:=OriginalImage.Picture.Bitmap.ScanLine[i];  
    29. for j:=0 to TemporaryImage.Picture.Width-1 do  
    30. begin  
    31. temp:=((originalPixelPointer[3*j]-CenterScrollBAr.Position)  
    32. *exp(ContrastScrollBar.Position/50))  
    33. + CenterScrollBar.Position;  
    34. if temp<0>255 then temp:=255;  
    35. pixelPointer[3*j]:=round(temp);  
    36. temp:=((originalPixelPointer[3*j+1]-CenterScrollBAr.Position)  
    37. *exp(ContrastScrollBar.Position/50))  
    38. + CenterScrollBar.Position;  
    39. if temp<0>255 then temp:=255;  
    40. pixelPointer[3*j+2]:=round(temp);  
    41. temp:=((originalPixelPointer[3*j+2]-CenterScrollBAr.Position)  
    42. *exp(ContrastScrollBar.Position/50))  
    43. + CenterScrollBar.Position;  
    44. if temp<0>255 then temp:=255;  
    45. pixelPointer[3*j+2]:=round(temp);  
    46. end;  
    47. end;  
    48. TemporaryImage.Refresh;  
    49. end;  
    50. except  
    51. begin  
    52. Free;  
    53. ShowMessage('Cannot complete the operation');  
    54. end;  
    55. end;  
    56. end;  

    In the code shown above, you can see the contrast gain is computed as exp(ContrastScrollBar.Position/50), with this formula, when the scroll bar position is zero (the default), the gain will be exp(0/50)=1, and at maximum the contrast gain will be exp(100/50)=100, and at the minimum the contrast gain will be exp(-100/50)=1/100.
  4. On the ContrastForm, double clicks the OKButton component, you'll be directed to its event handler, then edit as shown below:
    1. procedure TContrastForm.OKButtonClick(Sender: TObject);  
    2. begin  
    3. Applied:=true;  
    4. Close();  
    5. end;  
  5. Double click the CancelButton component in the ContrastForm, and you'll be directed to its event handler, edit as shown below:
    1.  procedure TContrastForm.CancelButtonClick(Sender: TObject);  
    2. begin  
    3. Applied:=false;  
    4. Close();  
    5. end;  
  6. To implement the decision whether the image on the source form will be modified or reverted to the original bitmap, edit the ContrastForm's OnClose event handler as shown below:
    1. procedure TContrastForm.FormClose(Sender: TObject; var Action: TCloseAction);  
    2. begin  
    3. if Applied=false then  
    4. TemporaryImage.Picture.Bitmap.Assign(  
    5. OriginalImage.Picture.Bitmap);  
    6. Action:=caFree;  
    7. end;  
Calling the GUI Module from The Main Application
To show the contrast enhancement interface and to connect the active image form to the contrast GUI, we need to add a new item in the main menu. Double click the main menu component in the main form, and add a Contrast menu item under menu Image (Image->Contrast, see Figure 2.

Figure 2. Contrast Menu Item

Write the event handler for the menu as shown below:
  1. procedure TMainForm.Contrast1Click(Sender: TObject);  
  2. begin  
  3. if ImageForm<>nil then  
  4. begin  
  5. ImageForm:=TImageForm(ActiveMDIChild);  
  6. try  
  7. begin  
  8. Application.CreateForm(TContrastForm,ContrastForm);  
  9. ContrastForm.SetContrast(ImageForm.Image1);  
  10. end;  
  11. except  
  12. ContrastForm.Free;  
  13. ShowMessage('Cannot complete the operation');  
  14. end;  
  15. end;  
  16. end;  
Figure 3. Contrast Processing Execution
Don't forget to add ContrastUnit under the uses in the MainUnit's implementation. Use menu File->Use Unit (Alt+F11). Now you can save, compile and run the executable. The execution look like figure 3.

Source Code Download
The source code can be downloaded here for Delphi 7 project, and here for the Turbo Delphi Explorer source code. Besides contains new source codes for contrast enhancement, if you compare to our previous brightness modification project's source codes, you'll see that in the codes for the brightness manipulation codes has also been updated to accommodate both two different image formats, pf8bit (8 bit monochrom/gray sacle) and pf24bit (true color). When applied to a monochrome image, sliding one scroll bar will move other two scroll bars to reflect that monochrome image doesn't have any separate RGB components.

Nenhum comentário:

Postar um comentário

Observação: somente um membro deste blog pode postar um comentário.

Max Gehringer