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
 Getting a file from a selection

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
jenswahl Posted - Jul 18 2013 : 06:12:39
Hello,

I want to work on photos (or scans) with pages of a comic. Mostly the photo shows more than
only the wanted page (a black background). To get only the page I use this code:


var
    ievSrc:     TImageEnView;
    iebmTmp:    TIEBitmap;
    ioTmp:      TImageEnIO;
    ptTmp:	TPoint;	//it's the point to get the background color
    
begin
    ...
    //get ptTmp....
    ...
    //beginning of getting the page    
    ievSrc.MagicWandMaxFilter := True;
    ievSrc.MagicWandTolerance := 40;
    ievSrc.MagicWandMode := iewExclusive;
    ievSrc.SelectMagicWand(ptTmp.X, ptTmp.Y, iespReplace);
    //here I see the selected page correctly
    ievSrc.InvertSelection;
    
    //copy the selection into a temp iebitmap for saving
    iebmTmp:=IEBitmap.Create;                
    ioTmp := TImageEnIO.Create(nil);
    ievSrc.CopySelectionToIEBitmap(iebmTmp);
    ioTmp.AttachedIEBitmap := iebmTmp;
    //I get the complete photo with white background! 
    ioTmp.SaveToFile('c:\Test\example.jpg');	
    ioTmp.Free;
    ievSrc.DeSelect;
    ievSrc.Blank;
    ievSrc.IEBitmap.Assign(iebmTmp);   
    //I see only the wanted page
    ievSrc.Update;
    iebmTmp.Free;
    ...
end;


The background on the photo is near black (second attatched file). At last I can show the page correctly on the ievSrc. But if I save it as a file from ievSrc (and also by saving iebmTmp) I have the same size like the original only with a white background (first attatched file).

How can I get a saved file only with the wanted page?

Best regards

Jens




8   L A T E S T    R E P L I E S    (Newest First)
jenswahl Posted - Jul 24 2013 : 02:35:36
Hello,

a little summary: my test-application runs now with good results. It works with photos or scanned images with a black (or other colored) background. The wanted page can be rotated and must not be centered in the photo. But a requirement is that a part of the wanted page lies on the centre of the photo.

What have I done:
Firstly I set the background color to transparency (and not to a not used color: thanks to w2m). Than I scan from the center of the photo to the left, right, upper and lower border where transparency begins.
Using two helper points on the upper border I get the rotation angle of the page. If this angle = 0 then it's easy to get the corner points of the page. If the angle <> 0 I have to use some trigonometric functions to get these points. In the end I have 8 points for creating the selection (point 9 of the array is the centre of the photo).
I have the front and rear page as a single page on a photo, the other pages are double pages on a photo. So I select the single pages automatically too.
After selection I copy the selection into another TIEBitmap, rotate it if angle <> 0 and save it.
The results are mostly good. For 9 photos with double pages and the front plus the rear page-photos (11 all with about 8 mega pixels each) it needs between 2:30 minutes till 3:00 minutes (the last if I have to rotate all pages).
I have to do some fine tuning but this is OK.
So the problem is solved to me. Thanks for all the help.

Jens

jenswahl Posted - Jul 21 2013 : 05:34:42
Hello,

William's suggestion doesn't give back the wanted solution. But with William's idea with transparenty I will replace my CalcImagePalette:
Using the MagicWand-function, setting the selection to transparenty and search from the middle of the image till finding the transparenty front will getting the outline. So it will work more faster.

I will report the result here.

Jens
jenswahl Posted - Jul 21 2013 : 05:11:16
Hello,

thanks to William again and also to Prg.
I also found that the "black" background isn't really black; there are some grey or white pixels included (if I show the image in 100% or more than I can see it) and so the inverted selected area is bigger as the page itself because the MagicWand doesn't include these pixels.
Manually isn't possible - I have about 800 Books and about 400 Comics - to much.
First I will try Willam's last suggestion and (if I doesn't get what I want) I will do the following:

var
iColorCount: Integer;

iRGB, iRGB2: TRGB;

aRGB: array of TRGB;


begin
iColorCount := ImageEnView1.Proc.CalcImageNumColors;
SetLength(aRGB, iColorCount + 1);
//but this needs a lot of time, on tests I got till 4..9 ...
//...minutes for one image!!!:
ImageEnView1.Proc.CalcImagePalette(aRGB, iColorCount);
...
end;
Maybe I resize the image before using CalcImagePalette to the half size to get a faster progress.
Than I want to find a NOT used color clNotUsed in aRGB and fill the selected area (selected by MagicWand) with this color. From the middle of the image the pixels scanning till finding clNotUsed. So I want to get the outline of the page. This will need a long long time - I know it. But the most MUST be done automatically.

Jens
w2m Posted - Jul 19 2013 : 08:44:11
I finally found something that works. The problem with using selections is magicwand does not just select a rectangular area of the comic image and each image that you scan will not be the same which makes setting the tolerance difficult. Also it is likely that the magicwand is not truly a selected rectangle and probably has small "holes" included as part of the selection. The approach I used is similar to my previous suggestion except that it crops away the transparent area (formerly the gray border) and leaves the comic image itself which is what I think you are looking for.

The bitmap before processing is 716x598 and the bitmap after processing is 587x598.

When you are scanning the image the success of any processing regardless of how you do it depends on getting a relatively "clean" scan. My success over the years cleaning up a scanned image using magicwand has been problematic at best. I recommend you give up on magicwand and selections in general because it is difficult to get the selection correct because of differences in each scan.

I suspect that the reason that ievSrc.CopySelectionToIEBitmap(ievDest.IEBitmap) copies the whole photo rather than the selection is because a rectangular area of the comic is not really selected with your technique and there are small selections inside the comic image itself, so when you copy the selection to the IEBitmap it copies the entire image.

I think if you just select the comic manually with miSelect that CopySelectionToIEBitmap would work as expected. Update: I just tried a manually selected rectangle around the comic and CopySelectionToIEBitmap works correctly. In fact after processing the selection, the result is a bitmap with the same dimensions that the procedure shown below produces... 587x598.

So I recommend you try this again:
procedure TForm1.Button1Click(Sender: TObject);
var
  iFilename: string;
begin
  if OpenPictureDialog1.Execute then
  begin
    iFilename := OpenPictureDialog1.FileName;
    if FileExists(iFilename) then
    begin
      Screen.Cursor := crHourGlass;
      try
        ImageEnVect1.Clear;
        ImageEnVect1.LayersClear;
        ImageEnVect1.RemoveAllObjects;
        { Load the image }
        ImageEnVect1.IO.LoadFromFile(iFilename);
        { The comic dimensions are 716 x 598 }
        ShowMessage('Dimensions: ' + IntToStr(ImageEnVect1.IEBitmap.Width) + ' x ' + IntToStr(ImageEnVect1.IEBitmap.Height));
        { Cast clWhite to the topleft of the image }
        ImageEnVect1.Proc.CastColor(10, 10, TColor2TRGB(clWhite), 20);
        { Cast clWhite to the topright of the image }
        ImageEnVect1.Proc.CastColor(ImageEnVect1.IEBitmap.Width - 10, 10, TColor2TRGB(clWhite),
          20);
        { Make the white transparent }
        ImageEnVect1.Proc.SetTransparentColors(TColor2TRGB(clWhite), TColor2TRGB(clWhite), 0);
        ImageEnVect1.Update;
        { Crop the transparent border }
        ImageEnVect1.Proc.CropTransparentBorder;
        { The comic dimensions are 587 x 598 }
        ShowMessage('Dimensions: ' + IntToStr(ImageEnVect1.IEBitmap.Width) + ' x ' + IntToStr(ImageEnVect1.IEBitmap.Height));
      finally
        Screen.Cursor := crDefault;
      end;
    end;
  end;
end;

William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
w2m Posted - Jul 19 2013 : 07:00:56
I have not tried this, but there are two parameters
procedure CopySelectionToIEBitmap(DestBitmap:TIEBitmap; FillBackground:boolean);

Description
CopySelectionToIEBitmap copies the current selection to the specified bitmap.
If FillBackground is true the background is filled using Background color, otherwise it is filled with image self.

Example
Try setting the last parameter to true or false to see if it works:
ImageEnView1.CopySelectionToIEBitmap( ImageEnView2.IEBitmap, False );

William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html
Prg Posted - Jul 19 2013 : 03:09:23
You can use
ievSrc.Proc.AutoCrop(15,ievSrc.IEBitmap.Pixels[0,0]);

15 is good value but you can use other after tests.
jenswahl Posted - Jul 19 2013 : 00:08:58
Hello,

Thank you to William, for your solution - but I get the same result like my example.
The most images are photos (faster and better resolution as a scanner)
I also tested:
- CopyFromPolygon: I get the rectabngle of the page but only in white
- CopySelectionToIEBitmap, SelCopyToClip: like my example
- CopyToBitmapWithAlpha after the code by William: the complete photo only in white

The real question to me is the following:
- ievSrc.SelectMagicWand(ptTmp.X, ptTmp.Y, iespReplace): works fine
- ievSrc.InvertSelection: works fine, shows the wanted page
- ievSrc.CopySelectionToIEBitmap(ievDest.IEBitmap): copies NOT the selection but the whole photo, why that?

Best regards

Jens
w2m Posted - Jul 18 2013 : 08:07:57
If you are getting the image from a scanner, most scanners have the ability to do a preview that selects only the comic and not the entire bed of the scanner... that way the scanned bitmap is only the comic.

But, you can convert the black to white and then remove the white so only the comic is visible:
procedure TForm1.Button1Click(Sender: TObject);
var
  iRGB: TRGB;
begin
  { Fill the area around the comic with white }
  { Cast clWhite to the topleft of the image }
  ImageEnVect1.Proc.CastColor(10, 10, TColor2TRGB(clWhite), 15);
  { Cast clWhite to the topright of the image }
  ImageEnVect1.Proc.CastColor(ImageEnVect1.IEBitmap.Width - 10, 10, TColor2TRGB(clWhite), 15);
  iRGB := TColor2TRGB(clWhite);
  { Make the white transparent }
  ImageEnVect1.Proc.SetTransparentColors(iRGB, iRGB, 0);
  ImageEnVect1.Update;
  ImageEnVect1.IO.SaveToFile('c:\Test\example.jpg');
end;


66.57 KB
William Miller
Adirondack Software & Graphics
Email: w2m@frontiernet.net
EBook: http://www.imageen.com/ebook/
Apprehend: http://www.frontiernet.net/~w2m/index.html