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

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Help with Objects and DPI
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

AndyColmes

USA
351 Posts

Posted - Feb 15 2012 :  23:21:34  Show Profile  Reply
I have an image scanned into an ImageEnVect at 150 DPI and some objects like rectangles are drawn on it and saved to a .iev file. But when an image of a different DPI is loaded into the Image such as a 300 DPI image, loading the objects back from the .iev file is no longer true to the size. How can I load the objects to their true size of the image in the ImageEnVect based on the DPI?

Thanks.

fab

1310 Posts

Posted - Feb 15 2012 :  23:40:34  Show Profile  Reply
Objects coordinates (and sizes) are relative to the image measured in pixels. Also, objects maintain their coordinates, in pixels, when reloaded.
Go to Top of Page

AndyColmes

USA
351 Posts

Posted - Feb 16 2012 :  00:10:41  Show Profile  Reply
I am using ObjLeft, ObjTop, etc. to get the coordinates in order to crop out the image defined by IEBOX rectangles. Maybe this is where I have a problem.

After loading another DPI image like 300 DPI, I load the .iev file (created from the 150 DPI image file), iterate through the objects and using ObjLeft, ObjTop, etc. values to CropSel the image pieces out. But somehow, the image pieces are wrong due to the size change. What would be the correct way to do this or if there is an easier way to crop out all the objects in one go?

Thanks.
Go to Top of Page

fab

1310 Posts

Posted - Feb 16 2012 :  00:49:11  Show Profile  Reply
Please do not consider DPI when dealing with objects: they relate only pixels.
Anyway, please could you provide a project (with sample images) that shows this problem? Maybe it could be a starting point for a future improvement.
Go to Top of Page

AndyColmes

USA
351 Posts

Posted - Feb 16 2012 :  09:34:00  Show Profile  Reply
>Objects coordinates (and sizes) are relative to the image measured in pixels. >Also, objects maintain their coordinates, in pixels, when reloaded.

If an .iev file is created using an image that is smaller, are you saying that if another image that is bigger is loaded and the same .iev file is then loaded, the .iev will automatically adjust to the size of the new image? I am unable to make this work. Could it be that TimageEnVect.SelectionBase is wrong? Or do I have to set the pixel size of the TImageEnVect?

Go to Top of Page

AndyColmes

USA
351 Posts

Posted - Feb 16 2012 :  09:38:15  Show Profile  Reply
Here is a snapshot of how it looks like for my problem. This is after loading a larger image but loading an .iev created from a smaller image.


42.65 KB
Go to Top of Page

fab

1310 Posts

Posted - Feb 16 2012 :  09:41:49  Show Profile  Reply
quote:
If an .iev file is created using an image that is smaller, are you saying that if another image that is bigger is loaded and the same .iev file is then loaded, the .iev will automatically adjust to the size of the new image?


No, it is exactly the opposite. Coordinates of objects are restored as is.
If you need to move/resize them, to adapt to the new image size, then you have to do it manually (or resize the image).

If you create a box at position 0,0 with width=100 and height=100, then it will be restored (after LoadFromFileIEV) at the same position and with the same size, independently by the current background image.
Go to Top of Page

AndyColmes

USA
351 Posts

Posted - Feb 16 2012 :  10:07:20  Show Profile  Reply
If after loading an image and loading the .iev file, is there a way to resample the image and the objects according? Right now, resample the image does not resample the objects.
Go to Top of Page

fab

1310 Posts

Posted - Feb 16 2012 :  10:29:17  Show Profile  Reply
You have to resample objects manually. They are not related (anchored) with the background image.
Following is a loop which move/resize all objects by a multiplier (1.2 in this example):
var
  i, hobj: integer;
  multiplier: double;
  rect: TRect;
begin
  multiplier := 1.2;   <--- application specific
  for i:=0 to ImageEnVect1.ObjectsCount-1 do
  begin
    hobj := ImageEnVect1.GetObjFromIndex(i);
    ImageEnVect1.GetObjRect(hobj, rect);
    rect.Left   := round(rect.Left * multiplier);
    rect.Top    := round(rect.Top * multiplier);
    rect.Right  := round(rect.Right * multiplier);
    rect.Bottom := round(rect.Bottom * multiplier);
    ImageEnVect1.SetObjRect(hobj, rect);
  end;
end;


Of course multiplier is application specific. I don't know how your images are and how objects are anchored when the image size change.
Maybe, if you create objects for an image of 150 DPI and then you load the same image with 300 DPI, then multiplier could be 2.0.

Also, that code doesn't handle resampling of text font sizes.

Go to Top of Page

AndyColmes

USA
351 Posts

Posted - Feb 16 2012 :  10:45:21  Show Profile  Reply
Can the multiplier be calculated from the pixel width and height?

For example, if the new width is N2 and the old width is N1, then the multiplier for width is Round( N2 / N1 )?
Go to Top of Page

fab

1310 Posts

Posted - Feb 16 2012 :  10:58:56  Show Profile  Reply
quote:
For example, if the new width is N2 and the old width is N1, then the multiplier for width is Round( N2 / N1 )?


This is application specific. N2/N1 could be a reasonable value but what about the vertical size? Does it maintain aspect ratio?
Go to Top of Page

AndyColmes

USA
351 Posts

Posted - Feb 16 2012 :  11:13:01  Show Profile  Reply
Fabrizio,

It does not seem to work when cropping out the images:

perW := 300 / 72; //New DPI X / Old DPI X
perH := 300 / 72; //New DPI Y / Old DPI Y

for k := 0 to ImageEnViewMaster.ObjectsCount - 1 do begin
hobj := ImageEnViewMaster.GetObjFromIndex(k);

ImageEnViewMaster.GetObjRect(hobj, rect);
rect.Left := round(rect.Left * perW);
rect.Top := round(rect.Top * perH);
rect.Right := round(rect.Right * perW);
rect.Bottom := round(rect.Bottom * perH);

TempImageEnView.Blank;
TempImageEnView.IO.LoadFromFile( FTempScanFile );
TempImageEnView.Proc.Crop(rect.Left, rect.Top, rect.Right, rect.Bottom);
TempImageEnView.Update;

targetfile := IncludeTrailingPathDelimiter( Trim( TargetRealEdit.Text ) ) + Trim( PrefixEdit.Text ) + Format('_%4.4d', [scount]) + sExt;

case FormatComboBox.ItemIndex of
0: begin
TempImageEnView.IO.SaveToFileBMP( targetfile );
end;
1: begin
TempImageEnView.IO.SaveToFileJpeg( targetfile );
end;
2: begin
TempImageEnView.IO.SaveToFileJP2( targetfile );
end;
3: begin
TempImageEnView.IO.SaveToFileTIFF( targetfile );
end;
4: begin
TempImageEnView.IO.SaveToFilePNG( targetfile );
end;
end;

scount := scount + 1;

end;

Where did I go wrong?
Go to Top of Page

fab

1310 Posts

Posted - Feb 16 2012 :  11:16:42  Show Profile  Reply
Where is SetObjRect?
I don't understand very well what your code should do, I'm sorry!
Go to Top of Page

AndyColmes

USA
351 Posts

Posted - Feb 16 2012 :  11:25:26  Show Profile  Reply
I think I got it right and it seems to work. As for the code, I am just getting the coordinates so I can use TImageEnVect.Proc.Crop to crop out the individual images defined by each rectangle object.

Thanks again, Fabrizio.
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: