IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Retailler une image scannée


Sujet :

Delphi

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 427
    Points : 1 326
    Points
    1 326
    Par défaut Retailler une image scannée
    Bonjour à toutes et à tous,

    J'aimerai réaliser une application qui scannerai un document afin de le sauver en image bmp, jpg, png.

    Seulement, j'aimerai pouvoir appliquer un resize (800 x 600) avant la sauvegarde.

    Voici mon code au cas ou quelqu'un aurait une idée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
    procedure TFormScan.BacquerirClick(Sender: TObject);
    Var
    ImgTmp:TImage;
    n:Integer;
    TestDib:HBitmap;
    begin
    ImgTmp:=TImage.Create(Self);
    TWAIN_SelectImageSource(0); 
    TWAIN_AcquireNative(0,0); 
    n:=TWAIN_GetNumDibs; 
    if n>=1 then
    begin
    TestDib:=TWAIN_GetDib(0); //Handle de la source
    CopyDibIntoImage(TestDib,ImgTmp); //Tansforme l'image DIB en Bitmap
    TWAIN_FreeNative(TestDib); //Libère la mémoire
    //Affiche dans "Image1" l'image "ImgTmp"
    Image1.Picture.Bitmap.Width:=ImgTmp.Width;
    Image1.Picture.Bitmap.Height:=ImgTmp.Height;
    Image1.Picture:=ImgTmp.Picture;
    end;
    end;
     
    procedure TFormScan.BenregistrerClick(Sender: TObject);
    begin
     
    SPD1.DefaultExt := GraphicExtension(TBitmap);
     with SPD1 {or SaveDialog1}do begin
         Filter     := 'Bitmap|*.bmp|Jpeg|*.jpg'{$IFDEF SAVEPNG}+'|Png|*.png'{$ENDIF};
         DefaultExt := '.bmp';
         if execute then
            case FilterIndex of
                 1 : with TBitmap.Create do
                     try
                       Assign(image1.picture.Graphic);
                       PixelFormat := pf24bit;
                       SaveToFile(ChangeFileExt(FileName,'.bmp'));
                     finally
                       Free;
                     end;
     
                 2 : with TJPEGImage.Create do
                     try
                       CompressionQuality  := 80; {75..85 : best ratio Size/Quality}
                       ProgressiveEncoding := True; {True : good for web or slow computer}
                       Assign(image1.picture.bitmap);
                       SaveToFile(ChangeFileExt(FileName,'.jpg'));
                     finally
                       Free;
                     end;
     
    {$IFDEF SAVEPNG}
      {$IFDEF PNGLIB1}{use PNGImage lib}
                 3 : with TPNGObject.Create do
                     try
                       Assign(image1.picture.bitmap);
                       CompressionLevel := 9; {9 : best quality but slow at hell}
                       InterlaceMethod  := imNone;
                       Filters          := [pfAverage];
                       Transparent      := false; 
                       RemoveTransparency;
                       SaveToFile(ChangeFileExt(FileName,'.png'));
                     finally
                       Free;
                     end;
      {$ELSE}
        {$IFDEF PNGLIB2}{use zPNG lib}
                 3 : with TPNGImage.Create do
                     try
                       Assign(image1.picture.bitmap);
                       CompressionLevel := clBest;
                       PixelFormat      := pf24bit;
                       SaveToFile(ChangeFileExt(FileName,'.png'));
                     finally
                       Free;
                     end;
        {$ELSE}{use Unknow/Custom PNG lib}
                 3 : with {INSERT NAME OF YOUR CUSTOM PNG CLASS HERE}.Create do
                     try
                       {INSERT PROPERTIES/PARAMETERS OF YOUR CUSTOM PNG CLASS HERE}
                       SaveToFile(ChangeFileExt(FileName,'.png'));
                     finally
                       Free;
                     end;
        {$ENDIF}
      {$ENDIF}
    {$ENDIF}
     
            end; {case}
      end; {with}
    end;
    Merci d'avance,

    @+,

    Cincap

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 427
    Points : 1 326
    Points
    1 326
    Par défaut J'ai oublié de dire...
    En fait, le scan est correct et la sauvegarde en jpg aussi.

    Seul hic c'est que le document chargé (page A4) représente un jpg de 1700 x 2338.

    Donc serait t'il possible de scanner les documents et d'appliquer un resize de 800 x 600 avant sauvegarde.

    Merci,

    @+,

    Cincap

  3. #3
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    ... serait t'il possible de scanner les documents et d'appliquer un resize de 800 x 600 avant sauvegarde.
    Pour le resize :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    function  ReDimImageSD3(const nomFichierImg: string; LargeurMax: Integer) : tBitMap;
    //        avec StretchDraw et TOleGraphic : Testé jusqu'à un format d'environ 1228x989x16Millions de couleurs
    const     FormatsSupportes = '.BMP.DIB.GIF.ICO.JIF.JPG.WMF.EMF';
    var       ext : string; FS : TFileStream; OleGraphic: TOleGraphic;
              img : TImage; BmpSource: TBitmap;
    begin     ext:=UpperCase(ExtractFileExt(nomFichierImg));
              if (ext='') or (pos(ext,FormatsSupportes)=0) then
              begin ShowMessage(ext+' = Format non supporté par ReDimImageSD3');
                    Result:=nil; EXIT;
              end;
              // Etape 1 : récup du BmpSource
              OleGraphic := TOleGraphic.Create;
              FS := TFileStream.Create(nomFichierImg, fmOpenRead or fmSharedenyNone);
              img:= tImage.Create(frmTrImages);
              BmpSource := TBitmap.Create;
              try
                 OleGraphic.LoadFromStream(FS);
                 img.Picture.Assign(OleGraphic);
                 with BmpSource do
                 begin PixelFormat:=pf24Bit;
                       Width:=img.Picture.Width;
                       Height:=img.Picture.Height;
                       Canvas.Draw(0, 0, img.Picture.Graphic);
                       LargSrc:=width; HautSrc:=Height;
                 end;
                 Application.ProcessMessages;
              finally
                 fs.Free;
                 img.free;
                 OleGraphic.Free;
              end;
              // Etape 2 : Redimensionnement conditionnel
              Result := TBitmap.Create;
              Result.PixelFormat := pf24Bit;
              try
                 if (BmpSource.Width > LargeurMax) then // Réduction taille
                 begin with Result do
                       begin Width := LargeurMax;
                             Height:= MulDiv(LargeurMax, BmpSource.Height, BmpSource.Width);
                             Canvas.StretchDraw(Rect(0,0,Result.Width,Result.Height), BmpSource);
                       end;
                 end else Result.Assign(BmpSource);    // Sinon Restit Taille réelle
                 Application.ProcessMessages;
              finally
                 BmpSource.Free;
              end;
    end; //ReDimImageSD3
    J'ai utilisé ReDimImageSD3 avec des formats inférieurs ou égaux à 1228x989x16Millions de couleurs, donc faudra l'essayer avec ton format de 1700 x 2338.

    Et pour la conversion du BitMap-Result en JPG avant sauvegarde :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function JPEGdeBMP(var BMP : tBitMap) : TJPEGImage;
    begin    Result:=TJPEGImage.Create;
             try
                with Result do
                begin PixelFormat := jf24Bit;
                      Grayscale   := False;
                      CompressionQuality := 80;
                      Scale := jsFullSize;
                      Assign(BMP);
                      JpegNeeded;
                      Compress;
                end;
                BMP.Dormant;             // Libère les ressources GDI
                BMP.FreeImage;           // Libère la mémoire.
             except
                on EInvalidGraphic do
                begin Result.Free; Result := nil; end;
             end;
             Application.ProcessMessages;
             BMP.Free;
    end;
    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 132
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 132
    Points : 1 418
    Points
    1 418
    Par défaut
    Salut,

    Pour redimensionner AVANT sauvegarde, remplace ton code qui dimensionne et "écrit" image1.Picture par la partie de calcul proprtionnel et stretchdraw de Gilbert Geyer


    devYan.

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 427
    Points : 1 326
    Points
    1 326
    Par défaut Merci et bien commenté !
    Bonjour à toutes et à tous,

    @ Gibert, merci pour ta solution, je vais essayer encore une fois malgré tous mes essais.

    Je pense que c'est plutôt dans la procédure "MultiTwain" qu'il faut appliquer le resize, en effet dans le code de l'application, j'utilise cette procédure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CopyDibIntoImage(TestDib,ImgTmp); //Tansforme l'image DIB en Bitmap
    Code de la procédure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    procedure CopyDIBIntoImage(hDIB: THandle; Image: TImage);
    var
       DibW, DibH, oldw, oldh: integer;
    begin
       Oldw := Image.Width;
       Oldh := Image.Height;
       DibW := TWAIN_DibWidth(hDib);
       DibH := TWAIN_DibHeight(hDib);
       Image.Width := DibW;  // temporarily enlarge image to ensure the whole
       Image.Height := DibH; // DIB gets copied
       TWAIN_DrawDibToDC(Image.Canvas.Handle, 0, 0, DibW, DibH, hDIB, 0, 0);
       Image.Width := oldw;
       Image.Height := oldh;
    end;
    @ Devyan, merci aussi pour ta réponse.

    @+,

    Cincap

  6. #6
    Membre actif Avatar de remixtech
    Profil pro
    Enseignant
    Inscrit en
    Février 2003
    Messages
    272
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Février 2003
    Messages : 272
    Points : 214
    Points
    214
    Par défaut
    Voir ici, je pense que ça peut t'aider...

    http://nono40.developpez.com/sources/source0036/

    Et une très bonne source de Sub0 ici qui permet d'appliquer un Anti Aliasing pendant le redimensionnement

    ftp://ftp-developpez.com/sub0/delphi/AAlias.zip


    Edit : L'anti aliasing permet de garder une plus belle image après le redimensionnement

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 427
    Points : 1 326
    Points
    1 326
    Par défaut Merci pour ta réponse
    @ remixtech, merci, je connaissai ces sources.

    Le 1er lien est mort pour cause, tu répètes 2x le http.

    Par contre, j'ai des erreurs avec les solutions proposées.

    Je persiste.

    @+,

    Cincap

  8. #8
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Par contre, j'ai des erreurs avec les solutions proposées.
    ... Il vaudrait mieux dire quelles erreurs pour chacune des solutions, cela permettrait d'avancer.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 427
    Points : 1 326
    Points
    1 326
    Par défaut Pour le resize c'est ok
    Bonjour à toutes et à tous,

    Concernant une photo scanée, le resize est ok.

    Par contre pour un document texte, le resize altère la qualité du text, donc ne convient pas pour créer un fichier pdf.

    En laissant le code tel quel, les photos et documents texte sont corrects mis à part la taille du document texte (A4) mais étant sauvé en jpg, cela n'alourdit pas l'application puisque le but final est de créer un fichier pdf.

    Merci à tous, je cloture le topic.

    A toutes fin pour le resize, j'ai simplement adapté le code de mon 1er topic :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    procedure TFormScan.BacquerirClick(Sender: TObject);
    Var
    
    ImgTmp:TImage;
    Bmp : TBitmap ;n:Integer;
    TestDib:HBitmap;
    begin
    ImgTmp:=TImage.Create(Self);
    BMP := Tbitmap.create;
    
    TWAIN_SelectImageSource(0); //Affichage de la boite de dialogue de sélection de la source
    TWAIN_AcquireNative(0,0); //Acquérit l'image
    n:=TWAIN_GetNumDibs; //Récupère le nombre d'image acquérit
    if n>=1 then
    begin
    TestDib:=TWAIN_GetDib(0); //Handle de la source
    CopyDibIntoImage(TestDib,ImgTmp); //Tansforme l'image DIB en Bitmap
    TWAIN_FreeNative(TestDib); //Libère la mémoire
    
    //Affiche dans "Image1" l'image "ImgTmp"
    {Image1.Picture.Bitmap.Width:=ImgTmp.Width;
    Image1.Picture.Bitmap.Height:=ImgTmp.Height;
    Image1.Picture:=ImgTmp.Picture; }
    
    BMP.Assign(ImgTmp.picture.graphic);
        BMP.width := sp1.value;
        BMP.height := sp2.value;
        BMP.pixelformat := pf24bit;
    
       SetStretchBltMode(BMP.Canvas.Handle,HALFTONE);
    
       BMP.Canvas.StretchDraw(Rect(0,0,sp1.value,sp2.value),ImgTmp.picture.bitmap);
    
      image1.Picture.Assign(bmp);end;
    end;
    @+,

    Cincap

  10. #10
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 132
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 132
    Points : 1 418
    Points
    1 418
    Par défaut
    Citation Envoyé par cincap Voir le message
    Par contre pour un document texte, le resize altère la qualité du text, donc ne convient pas pour créer un fichier pdf.
    Dans ce cas, c'est que l'algorithme de redimensionnement ne convient pas (StretchDraw fait un redimensionnement "rapide" dit taille de pixel, pixel resize, il me semble)

    En utilisant GDI+ (ou d'autres bibliothèques graphiques) tu peux réaliser des redimensionnements d'image avec d'autres algorithmes qui donnent de meilleurs résultat avec le texte.

    Yan.


    devYan.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Redresser une image scannée contenant des images et du texte
    Par Rodrigue dans le forum Traitement d'images
    Réponses: 5
    Dernier message: 18/12/2011, 11h47
  2. retailler une image
    Par Luke spywoker dans le forum Tkinter
    Réponses: 4
    Dernier message: 21/02/2011, 09h17
  3. Retailler une image et enregistrer sous en .jpg
    Par multimania dans le forum VBA Access
    Réponses: 2
    Dernier message: 25/01/2011, 09h58
  4. Récupérer une image scannée dans JAI
    Par roxor972 dans le forum Graphisme
    Réponses: 3
    Dernier message: 08/01/2009, 08h55
  5. Compresser et retailler une image jpg à l'upload
    Par alltec dans le forum Imagerie
    Réponses: 6
    Dernier message: 23/01/2007, 17h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo