Problème avec un Zoom sur une image

Cjvg Messages postés 330 Date d'inscription mercredi 6 décembre 2000 Statut Membre Dernière intervention 26 octobre 2017 - 24 août 2012 à 11:06
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 - 27 août 2012 à 12:50
Bonjour,

J' ai un problème de mémoire (erreur 480) en voulant zoomer une Image
Je n'ai rien trouvé sur les sites pour m'aider à trouver le remède.
Ce qui m'ennuie c'est que je voudrais utiliser un facture d'agrandissement beaucoup grand.

Private Sub SizeImage(Picture As PictureBox, ImageSize As Picture, WidthImage As Single, HeightImage As Single)
On Error GoTo Onsote

Picture.Picture = LoadPicture("")
Picture.Width = WidthImage '<---- 55260
Picture.Height = HeightImage '<---- 55800
Picture.PaintPicture ImageSize, 0, 0, WidthImage, HeightImage ' <---Erreur 480
Picture.Refresh
Exit Sub

Onsote:

IrowZoom = IrowZoom - 1
If IrowZoom < 5 Then
IrowZoom = 4

Alors, si vous avez la réponse........

Merci encore

15 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 août 2012 à 11:23
Bonjour,
Tu confonds la propriété Picture d'une pictureBox avec l'objet picture. Ton objet ImageSize n'est pas utilisable.
Plus gênant encore :
Picture As PictureBox

qui fait que VB perd alors complètement le nord
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 août 2012 à 11:29
Par ailleurs : un défaut de mémoire (insuffisance) provoquerait également l'erreur 480
Tu as enfin oublié de préciser en quelle échelle (scalemode) tu travailles.

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 août 2012 à 11:41
Passe à ta sub :
- la picturebox toto d'affichage. Donne-lui un autre nom que "Picture"
- la picturebox titi de l'image à zoomer
dans ta sub : (dans PicturePaint) :
- utilise en paramètre 1 : toto
- utilise en paramètre 2 : titi.picture
etc ...
PS : J'ai écrit "la picturebox titi" car je ne sais pas d'où vient l'image (et son scalemode).
Si vient d'une stdPicture : attention : va falloir "ramener" dans la bonne échelle.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
Cjvg Messages postés 330 Date d'inscription mercredi 6 décembre 2000 Statut Membre Dernière intervention 26 octobre 2017
24 août 2012 à 12:13
Bonjour Mr UcFoutu

J'ai oublié de préciser que le zoom fonctionne normalement tant que les dimensions ne dépassent pas: Width 43287 et Height 43710. Au delà, on tombe en erreur.

En ce qui concerne le scalemode de la picture il est initialisé à Twips.

J'ai modifié la procédure comme je pense avoir compris (voir ci-dessous). Rien de changé.


Private Sub SizeImage(APicture As PictureBox, AImageSize As Picture, WidthImage As Single, HeightImage As Single)
On Error GoTo Onsote

APicture.Picture = LoadPicture("")
APicture.Width = WidthImage
APicture.Height = HeightImage
APicture.PaintPicture AImageSize, 0, 0, WidthImage, HeightImage
APicture.Refresh
Exit Sub


-
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 août 2012 à 13:55
Je viens de faire ce petit essai sans aucun problème :
Sur un Form :
- une picturebox Picture1
- une picturebvox Picture2
- un bouton Command1
ce code

Private Sub Form_Initialize()
  Me.ScaleMode = vbPixels
  With Picture1
    .ScaleMode = vbPixels
    .AutoSize = True
    .Picture = LoadPicture("d:\bateau.bmp") 'mets ton image à toi
  End With
  With Picture2
    .AutoRedraw = True
    .ScaleMode = vbPixels
  End With
End Sub
Private Sub Command1_Click(Index As Integer)
 Dim coef As Integer
  coef = 5 ' ici le coeffricient à appliquer au "zoom"
  loupons Picture1, Picture2, coef
End Sub
Private Sub loupons(source As PictureBox, desti As PictureBox, coef As Integer)
  With desti
    .Cls
    .Width = source.Width * coef
    .Height = source.Height * coef
  End With
  desti.PaintPicture source.Picture, 0, 0, desti.Width, desti.Height
End Sub

Je mets tout en échelle de pixels pour éviter (en twips, de dépasser un sibngle). Le Form luoi-même est mis en pixels (because sinon les dimensions seront faussées, puisque calculées dans l'échelle du Form, hein ...)
Reste ce que je t'ai dit plus haut à propos de la mémoire disponible sur ta machine. Seule sa saturation dépassement, avec ce code, causerait un problème que ne saurait résoudre VB (ni quelqu'autre langage de développement, d'ailleurs)

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
Cjvg Messages postés 330 Date d'inscription mercredi 6 décembre 2000 Statut Membre Dernière intervention 26 octobre 2017
24 août 2012 à 14:40
J'ai fais un essai avec l' exemple donné.

- Avec un facteur 6, c'est OK. (Le Zoom est identique à celui de mon programme)

- Avec un facteur = 7, l'exécution tombe en erreur (Problème identique à celui de mon programme.)

Mon ordinateur manque probablement de mémoire ?................

--------------------------------------------------------------------------------------------

Autre sujet:
J'ai téléchargé un projet sur VB. Il tombe également en erreur comme je l'indique à l'adresse ci-dessous.

http://www.vbfrance.com/codes/RECUPERATION-URL-SOURCE-HTML-DERNIERE-PAGE-WEB-AFFICHEE_54537.aspx


Merci encore.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 août 2012 à 15:03
Tu as donc un problème de dépassement de mémoire disponible et le subis.
Et (comme dit plus haut) ce ne sera pas celui d'un langage de développement, mais celui de ta machine.
Une solution, peut-être :
te contenter de "grossir" telle ou telle autre partie (comme avec une loupe que tu déplacerais).
PS : un dépassement/saturation de mémoire disponible peut également surgir si ton programme crée des objets sans jamais les "tuer". Tu es peut-être dans un tel cas (mais je ne vois qu'une partie de ton code et ne peux donc vérifier cet aspect éventuel )
Voilà. On a fait le tour en l'état des choses dites.




________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
Cjvg Messages postés 330 Date d'inscription mercredi 6 décembre 2000 Statut Membre Dernière intervention 26 octobre 2017
24 août 2012 à 15:22
Mon programme est très gros ! Je vais encore le décortiquer pour essayer de gagner de la place et supprimer ou "Tuer" les objets non actifs s'il y en a.

Cela dit, j'ai malgré tout un doute sur la possibilité d'augmenter le facteur de Zoom de mon programme compte tenu que l'exécution d'un mini projet d'une quinzaine de lignes tombe également en erreur.

Merci encore pour ce support.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
24 août 2012 à 18:44
Ce n'est pas le nombre de lignes de code, qui vient encombrer significativement la mémoire. Ce seraient plutôt des objets, en particulier et entre autres, des images trop nombreuses et/ou de taille importante à un instant t.
Pour que tu comprennes mieux :
Dans le bout de code que je t'ai montré, par exemple :
l'image chargée dans picture1 ("bateau.bmp") "pèse" 198 KO.
Je peux l'aggrandir 20 fois (coef = 20) et l'afficher dans picture2. Il ne m'est pas possible, par contre, de l'afficher en appliquant un coef de 21.
Lorsque l'on applique le coef 20, le nombre de pixels est multiplié par 400 (198000 * 400 = 79.2 Mega octets !). C'est TRES TRES TRES lourd, surtout avec la propriété AutoRedraw mise à True !
A coef 21 >> 87.318 mega-octets et ===>> autoredraw ne peut suivre sur ma machine ===>> erreur 480
J'espère que c'est maintenant plus clair pour toi ainsi dit.
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
Cjvg Messages postés 330 Date d'inscription mercredi 6 décembre 2000 Statut Membre Dernière intervention 26 octobre 2017
24 août 2012 à 19:39
Je sais que c'est très gros!

J'ai utilisé Paintpicture pour afficher la même image que celle que j'affiche avec mon programme.
il y a une énorme différence entre le zoom maxi de Paintpicture et le mien.
- Cependant, la taille de l'image est la même, la mémoire de mon ordinateur est constante, la taille des programmes ne doit sûrement pas jouer sur le résultat. Reste le langage et la technique utilisée.

Bref je suis contraint à mon grand regrêt d'utiliser Paint.

Merci encore pour toutes ces explications.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
25 août 2012 à 10:54
Bonjour, cjvg
Pardonne-moi de revenir sur ce point, mais il me semble important de le faire, car cette discussion, si elle se terminait sur ton dernier message, risquerait d'induire en erreur d'autres visiteurs éventuels.
Je préfère donc clarifier un peu mieux les choses.
Ce n'est pas la méthode PaintPicture, qui est en cause, mais la propriété Autoredraw.
Mise à True, cette propriété a pour effet de créer en mémoire un DDB (Device-Dependant BitMap).
C'est ce DDB qui est constamment utilisé ensuite pour redessiner chaque fois que nécessaire.
Les limites de ce DDB ne dépendent pas du langage de développement, mais bel et bien du système d'exploitation, mais également de la machine elle-même.
Je conseille à ceux qui seraient intéressé par cet aspect de consacrer un peu de leur temps et de leur attention à cet excellent article à ce sujet :
Tapez le texte de l'url ici.
Il est écrit en anglais et je ne trouve nulle part l'équivalent en français. Dommage !
On y trouve quelques astuces et recommandations pour tendre à pallier certaines difficultés. La plus intéressante suggère l'écrire soi-même le en mémoire (mais dans un DIB plutôt que dans un DDB). Problème dans ce cas, toutefois : lenteurs pour recharger l'image dans son contrôle.
Un petit bout de code pour ceux qui voudraient savoir ce que coûterait le DDB d'une image dans une picturebox. Ce serait le coût supplémentaire généré par AutoRedraw = True
Une picturebox avec l'image de son choix, un bouton de commande et ce code tout bête :

Private Declare Function GetObject Lib "gdi32.dll" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, ByRef lpObject As Any) As Long
Private Type BITMAP
    bmType As Long
    bmWidth As Long
    bmHeight As Long
    bmWidthBytes As Long
    bmPlanes As Integer
    bmBitsPixel As Integer
    bmBits As Long
End Type

Private Sub Command1_Click()
    Dim bmp As BITMAP
     GetObject Picture1.Picture.Handle, Len(bmp), bmp
    MsgBox bmp.bmBits
End Sub

Voilà pour terminer ma participation.
En priant cjvg de ne pas y voir autre chose que la volonté d'éclairer mieux.



________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
25 août 2012 à 11:10
Ah oui. Je suis lent ce matin ...
Les plus éveillés s'apercevront vite de l'existence d'un aspect non négligeable :
Le "coût" estimé du DDB pourra dépendre d'autres facteurs conjoncturels, dont l'état de la machine à un instant t.
Faites donc l'expérience suivante :
- Lancez : un co^yut obtenu
- fermez
- relancez à un autre moment, machine dans un autre "état" ===>> un coût pouvant être différent.

Le moyen le plus facile de "modifier l'état" à coupo sur :
Après avoir "pesé" le coût avec la seule Picture1 sur le Form :
Ajoutez une picture2 avec une image
Relancez ===>> le coût du DDB de la picture1 (pourtant restée la même) est alors différent.
Intéressant, non ?

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
25 août 2012 à 22:30
Voilà !
J'ai laissé passer suffisamment de temps pour passer à la suite, cjvg.
Tu sais maintenant que c'est la création du DDB nécessaire à la propriété AutoRedraw (si = True) qui est la responsable de tes malheurs, pas la méthode PaintPicture.
Comment faire avecx ?
Ben ... tout dé^pend de ce que toi, tu veux ensuite faire de l'image aggrandie. Si non destinée ensuite à d'autres "travaux" sur l'aggrandissement réalisé (si_, donc, il ne s'agit que d'une visualisation, tu peux utliser PaintPicture de deux manières différentes, parmi lesquelles choisir en fonction de la finalité (que je ne connais pas) de ton appli.
Un Form avec, dessus, la picturebox Picture1, une picturebox Picture2, une scrollbar horizontale Hscroll1 et vois ces deux codes :
Code 1 (on va jouer en donnant du temps au temps) :
Private coef As Single, source As PictureBox, desti As PictureBox

Private Sub Form_Initialize()
  Me.ScaleMode = vbPixels
  With Picture1
    .ScaleMode = vbPixels
    .AutoSize = True
    .Picture = LoadPicture("d:\bateau.bmp") 'mets ton image à toi
  End With
  With Picture2
    .ScaleMode = vbPixels
    .AutoRedraw = False
  End With
  With HScroll1
    .Max = 100
    .Min = -100
    .Value = 1
  End With
  Set source = Picture1
  Set desti = Picture2
  coef = 1
End Sub

Private Sub HScroll1_Change()
  If desti Is Nothing Then Exit Sub
  coef = IIf(HScroll1.Value >= 1, HScroll1.Value, (100 + HScroll1.Value) / 100)
  With desti
    .Cls
    .Width = source.Width * coef
    .Height = source.Height * coef
    DoEvents ' ce Doevents est là très important
    .PaintPicture source.Picture, 0, 0, desti.Width, desti.Height
  End With
End Sub


Code 2 (on va jouer avec l'évènement Paint, en y utilisant PaintPicture) :
Private coef As Single, source As PictureBox, desti As PictureBox

Private Sub Form_Initialize()
  Me.ScaleMode = vbPixels
  With Picture1
    .ScaleMode = vbPixels
    .AutoSize = True
    .Picture = LoadPicture("d:\bateau.bmp") 'mets ton image à toi
  End With
  With Picture2
    .ScaleMode = vbPixels
    .AutoRedraw = False
  End With
  With HScroll1
    .Max = 100
    .Min = -100
    .Value = 1
  End With
  Set source = Picture1
  Set desti = Picture2
  coef = 1
End Sub

Private Sub HScroll1_Change()
  coef = IIf(HScroll1.Value >= 1, HScroll1.Value, (100 + HScroll1.Value) / 100)
  Picture2_Paint
End Sub

Private Sub Picture2_Paint()
  If desti Is Nothing Then Exit Sub
  With desti
    .Cls
    .Width = source.Width * coef
    .Height = source.Height * coef
    .PaintPicture source.Picture, 0, 0, desti.Width, desti.Height
  End With
End Sub

Dans un cas comme dans l'autre : on lance et on fait varier la scrollbar (que je traite tant en aggrandissement qu'en réduction)

Chacune de ces deux méthodes à ses avantages et ses inconvénients par rapport à l'autre.
Le choix que tu feras ne dépendra que de la finalité de ton appli et ce sera à toi seul de le faire.
Relis bien le début de ce message : bon à une condition : qu'il ne s'agit que de visualiser, hein.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
Cjvg Messages postés 330 Date d'inscription mercredi 6 décembre 2000 Statut Membre Dernière intervention 26 octobre 2017
27 août 2012 à 12:37
Bonjour,

J'ai fais des essais avec les deux méthodes présentées.
Pour avoir un zoom plus fin, j'ai ajouté les deux instructions suivantes:

Coef = Coef * 0.1
Text1.text = Coef


L'affichage ne se fait plus correctement à partir d'un coefficient à 6.4 6.5.
--------------------------------------------------------------------------------------------

Toujours avec les mêmes instructions
Pour réduire la taille de l'image affichée, j'ai plaçé la Picture2 dans une autre picture.
Idem - L'affichage ne se fait plus correctement à partir d'un coefficient 6.4 6.5.
En plaçant des Vscroll et HscrollBar pour déplaçer l'image, j'ai été confronté à d'autres problèmes.

J'ai passé toute l'après-midi d'hier et cette matinée à faire des essais sans trouver
la solution du problème, j'ai donc décidé d'en rester là.

Cela dit, merci encore pour cette assistance.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
27 août 2012 à 12:50
Oui.
Mais il est alors probable (l'affichage ne se fait plus "correctement") que tu es alors confronté à un autre problème lié aux capacités de ta carte graphique. Ce pourrait être le cas si l'image de base (avant agrandissement) est elle-meme très gourmande.
Il sera alotrs peut-être astucieux (voir ce que j'en ai dit plus haut) de ne pas tout agrandir, mais de n'agrandir que la partie qui intéresse. PaintPicture le permet. Le tout devrait alors être accompagné de calculs arithmétiques simples, mais très précis.
Rien d'autre "dans mon sac".


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
Rejoignez-nous