ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Needing a oval crop.

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
BillM Posted - Dec 02 2017 : 20:43:05
I work for a funeral home corporation and need to write a tool that makes it easy on our employees to perform two common tasks. One is to crop and resize a photo so that we can print an 11x14 photo. No problems on this - it is done.

The second task is to crop an image to contain the face with little else detail, then to create an oval picture from this.

The following code shows what I am doing and the attachments shows the results of each step in the process.

There are two speed buttons that allow the user to select which task they will be doing and the crop settings are set to enforce the aspect ratios we need.

The first two methods below are the event handlers for these two buttons.

An OnIdle method sets the visible flag of another button to allow the user to carry out the cropping and resizing of the photos once the cropping area has been drawn. The event handler for that button is btnCropAndResizeClick. Regardless as to which speed button is pressed, the photo will be cropped and resized. If the OBIT speed button is pressed, then additional processes are implemented on the image. Namely selecting an ellipse and then masking out the area outside the ellipse.

Stage2.jpg is the cropped resized image with a size of 650 x 900 which is exactly the size we want. The next step is where things are falling apart... see Stage3.jpg

I am trying to select an ellipse with the center of the ellipse in the exact center of the image, the top of the ellipse at the top most pixel in the image, the bottom of the ellipse at the bottom most pixel. and finally the left and right edges of the ellipse to be at the corresponding left and right edges of the image. As can be seen the right, bottom, and left sides of the ellipse extends past the edges of the image. Am I doing something wrong?

Stage6.jpg shows the final results with the squared edges on the right, bottom, and left.

The .zip attachment has images from the six stages that I captured with the SaveTempFile command.



procedure TfrmMain.btnCrop11x14Click(Sender: TObject);
begin
  if btnCrop11x14.SpeedButtonOptions.Down then
  begin
    fTargetW := 3300;
    fTargetH := 4200;

    imgView.CropToolInteraction.Options := [iecoAllowResizing, iecoAllowMoving, iecoSideGripsRespectLocks];
    imgView.CropToolInteraction.LockAspectRatio := fTargetW/fTargetH;

    imgView.MouseInteract := [miCropTool];
  end
  else
  begin
    imgView.CropToolInteraction.Options := [];
    imgView.MouseInteract := [];
  end;
end;

procedure TfrmMain.btnCropObitClick(Sender: TObject);
begin
  if btnCropObit.SpeedButtonOptions.Down then
  begin
    fTargetW := 650;
    fTargetH := 900;

    imgView.CropToolInteraction.Options := [iecoAllowResizing, iecoAllowMoving, iecoSideGripsRespectLocks];
    imgView.CropToolInteraction.LockAspectRatio := fTargetW/fTargetH;

    imgView.MouseInteract := [miCropTool];
  end
  else
  begin
    imgView.CropToolInteraction.Options := [];
    imgView.MouseInteract := [];
  end;
end;

procedure TfrmMain.btnCropAndResizeClick(Sender: TObject);
begin
  fStage := 1;

  if imgView.CropToolInteraction.Selected then
  begin
    imgView.CropToolInteraction.Crop;
    imgView.Update;
    SaveTempFile(imgView, fStage);

    imgView.Proc.Resample(fTargetW,fTargetH);
    imgView.Update;
    SaveTempFile(imgView, fStage);

    if btnCropObit.Down then
    begin
      imgView.SelectEllipse(imgView.fBitmap.Width div 2, imgView.fBitmap.Height div 2, imgView.fBitmap.Width, imgView.fBitmap.Height);

      imgScreenCapture.IO.CaptureFromScreen(iecsForegroundWindowClient, -1);
      SaveTempFile(imgScreenCapture, fStage);

      MaskSelectedEllipse(Sender);
    end;

    imgScreenCapture.IO.CaptureFromScreen(iecsForegroundWindowClient, -1);
    SaveTempFile(imgScreenCapture, fStage);

    SaveTempFile(imgView, fStage, true);

    btnCrop11x14.Down := false;
    btnCropObit.Down := false;

  end;
end;

procedure TfrmMain.MaskSelectedEllipse(Sender: TObject);
var
  iRGB: TRGB;
begin
  imgView.InvertSelection;
  imgView.Proc.Fill(clBlack);
  imgView.DeSelect;

  imgScreenCapture.IO.CaptureFromScreen(iecsForegroundWindowClient, -1);
  SaveTempFile(imgScreenCapture, fStage);

  iRGB := TColor2TRGB(clBlack);

  imgView.Proc.SetTransparentColors(iRGB, iRGB, 0);
  imgView.BackgroundStyle := iebsChessboard;
  imgView.IO.Params.BitsPerSample := 8;
  imgView.IO.Params.SamplesPerPixel := 4;

  imgView.Update;
end;


attach/BillM/2017122203910_images.zip
455.98 KB
2   L A T E S T    R E P L I E S    (Newest First)
BillM Posted - Dec 04 2017 : 19:09:49
Perfect. Thank you!
xequte Posted - Dec 04 2017 : 17:27:50
Hi Bill

The following will make a circular selection of entire image and then crop it

  ImageEnView1.SelectionBase := iesbBitmap;
  ImageEnView1.SelectEllipse(ImageEnView1.IEBitmap.Width div 2,
                             ImageEnView1.IEBitmap.Height div 2,
                             ImageEnView1.IEBitmap.Width,
                             ImageEnView1.IEBitmap.Height);
  ImageEnView1.Proc.CropSel();


Which is actually the same as calling:

  ImageEnView1.Proc.RoundImage(ImageEnView1.IEBitmap.Width div 2,
                               ImageEnView1.IEBitmap.Height div 2);



Note: You should never directly access ImageEnView1.fBitmap. You should set ImageEnView1.LegacyBitmap to false, and use ImageEnView1.IEBitmap.

Nigel
Xequte Software
www.xequte.com
nigel@xequte.com