Home All Groups Group Topic Archive Search About

write a bitmap into an array of picture boxes

Author
20 May 2009 9:00 PM
caver_dave
I have a small app that writes an array of pic boxes to a picbox in order to
save it as a bitmap
*sample code for one line *
Picture5.PaintPicture Picture1(0).Image, 0, 0, 1, 1
Picture5.PaintPicture Picture1(1).Image, 1, 0, 1, 1
Picture5.PaintPicture Picture1(2).Image, 2, 0, 1, 1
Picture5.PaintPicture Picture1(3).Image, 3, 0, 1, 1
Picture5.PaintPicture Picture1(4).Image, 4, 0, 1, 1
Picture5.PaintPicture Picture1(5).Image, 5, 0, 1, 1
Picture5.PaintPicture Picture1(6).Image, 6, 0, 1, 1
Picture5.PaintPicture Picture1(7).Image, 7, 0, 1, 1
Picture5.PaintPicture Picture1(8).Image, 8, 0, 1, 1
Picture5.PaintPicture Picture1(9).Image, 9, 0, 1, 1
* the other lines follow suit *

I am not sure how to go about doing the reverse

Picture1(0).Picture = Picture5.Picture,0, 0, 1, 1

i know that this is not correct
any help with my problem would be greatly appreciated

Thanks in advance

Author
21 May 2009 12:17 AM
Bee
Are you lucky.
I was just no working in this sub.

Air code extracted from working code.
Play with this and it will take a portion of an image and put it into
another picturebox.
I leave the sizing of the destination to you.
Just make sure the aspect the same as the portion being snapped.
This code is for a general case of anything in picSnap to picHolder.
Have fun.

Public Type tStretch
    picDst As PictureBox    ' Destination PictureBox
    lDstLeft As Long
    lDstTop As Long
    lDstWd As Long
    lDstHt As Long
    '
    picSrc As PictureBox    ' Source PictureBox
    lSrcLeft As Long
    lSrcTop As Long
    lSrcWd As Long
    lSrcHt As Long
End Type
'
Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x
As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal
hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As
Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Public Declare Function SetStretchBltMode Lib "gdi32" (ByVal hdc As Long,
ByVal hStretchMode As Long) As Long

Private Sub Stretch()

    Dim ts As tStretch

    ' cropped part of the original
    Set ts.picSrc = picSnap
    ts.lSrcLeft = ' location in picSnap
    ts.lSrcTop =  ' location in picSnap
    ts.lSrcWd =  ' location in picSnap
    ts.lSrcHt =  ' location in picSnap

    ' into final holder
    Set ts.picDst = picHolder
    ts.lDstLeft = 0
    ts.lDstTop = 0
    ts.lDstWd = picHolder.Width
    ts.lDstHt = picHolder.Height

    ' copy the cropped part
    bRet = StretchPic(ts, True)

End Sub

Public Function StretchPic(ts As tStretch, Optional bStretchMode As Boolean
= False) As Boolean
'
    On Error GoTo StretchPicErr
    Dim lRet As Long
'
    If bStretchMode Then
        ' Stretch it with SetStretchBltMode '
        lRet = SetStretchBltMode(ts.picDst.hdc, vbPaletteModeContainer)
    End If
    '
'
' dwROP values
'    BLACKNESS      Turns all output black.
'    DSTINVERT      Inverts the destination bitmap.
'    MERGECOPY      Combines the pattern and the source bitmap using the
Boolean AND operator.
'    MERGEPAINT     Combines the inverted source bitmap with the destination
bitmap using the Boolean OR operator.
'    NOTSRCCOPY     Copies the inverted source bitmap to the destination.
'    NOTSRCERASE    Inverts the result of combining the destination and
source bitmaps using the Boolean OR operator.
'    PATCOPY        Copies the pattern to the destination bitmap.
'    PATINVERT      Combines the destination bitmap with the pattern using
the Boolean XOR operator.
'    PATPAINT       Combines the inverted source bitmap with the pattern
using the Boolean OR operator. Combines the result of this operation with the
destination bitmap using the Boolean OR operator.
'    SRCAND         Combines pixels of the destination and source bitmaps
using the Boolean AND operator.
'    SRCCOPY        Copies the source bitmap to the destination bitmap.
'    SRCERASE       Inverts the destination bitmap and combines the result
with the source bitmap using the Boolean AND operator.
'    SRCINVERT      Combines pixels of the destination and source bitmaps
using the Boolean XOR operator.
'    SRCPAINT       Combines pixels of the destination and source bitmaps
using the Boolean OR operator.
'    WHITENESS      Turns all output white.
'
    lRet = StretchBlt(ts.picDst.hdc, ts.lDstLeft, ts.lDstTop, ts.lDstWd,
ts.lDstHt, ts.picSrc.hdc, ts.lSrcLeft, ts.lSrcTop, ts.lSrcWd, ts.lSrcHt,
vbSrcCopy)
'
' If the function fails, the return value is zero.
'
    ts.picDst.Refresh
    StretchPic = (lRet <> 0)
'
StretchPicExit:
    Exit Function
'
StretchPicErr:
    'Debug.Print Err.Description
    Debug.Assert False
    Resume StretchPicExit
'
End Function 'StetchPic


Show quoteHide quote
"caver_dave" wrote:

> I have a small app that writes an array of pic boxes to a picbox in order to
> save it as a bitmap
> *sample code for one line *
> Picture5.PaintPicture Picture1(0).Image, 0, 0, 1, 1
> Picture5.PaintPicture Picture1(1).Image, 1, 0, 1, 1
> Picture5.PaintPicture Picture1(2).Image, 2, 0, 1, 1
> Picture5.PaintPicture Picture1(3).Image, 3, 0, 1, 1
> Picture5.PaintPicture Picture1(4).Image, 4, 0, 1, 1
> Picture5.PaintPicture Picture1(5).Image, 5, 0, 1, 1
> Picture5.PaintPicture Picture1(6).Image, 6, 0, 1, 1
> Picture5.PaintPicture Picture1(7).Image, 7, 0, 1, 1
> Picture5.PaintPicture Picture1(8).Image, 8, 0, 1, 1
> Picture5.PaintPicture Picture1(9).Image, 9, 0, 1, 1
> * the other lines follow suit *
>
> I am not sure how to go about doing the reverse
>
> Picture1(0).Picture = Picture5.Picture,0, 0, 1, 1
>
> i know that this is not correct
> any help with my problem would be greatly appreciated
>
> Thanks in advance
>
>
>
Author
21 May 2009 1:19 AM
Larry Serflaten
"caver_dave" <caverd***@discussions.microsoft.com> wrote
> I have a small app that writes an array of pic boxes to a picbox in order to
> save it as a bitmap

Have you heard of the PictureClip control that ships with VB?
http://msdn.microsoft.com/en-us/library/aa733665(VS.60).aspx

LFS
Author
21 May 2009 8:35 AM
Mike Williams
"caver_dave" <caverd***@discussions.microsoft.com> wrote in message
news:A54128D2-15D7-4CFA-A449-DCC1D9223320@microsoft.com...

>I have a small app that writes an array of pic boxes to a
> picbox in order to save it as a bitmap
> *sample code for one line *
> Picture5.PaintPicture Picture1(0).Image, 0, 0, 1, 1
> Picture5.PaintPicture Picture1(1).Image, 1, 0, 1, 1
> . . . . . I am not sure how to go about doing the reverse
> Picture1(0).Picture = Picture5.Picture,0, 0, 1, 1

It depends on whether your code (extract above) is drawing the original
Image into the "composite" Picture Box at the full Picture1(n).Image size or
whether it is reducing it to a thumbnail (it isn't possible to tell for
certain what you are doing simply by looking at your example code). If you
are drawing into the composite PicBox as a smaller thumbnail of the Image
then you cannot get back the original Image from the "composite thumbnail"
alone without a great loss of quality. In other words, you cannot expand the
thumbnail's size by stretching the thumbnail without the result becoming
"blocky". However I suspect that you are drawing into the composite at the
original Picture1(n).Image size, in which case you can get the appropriate
section of the composite back into the original Picture1(n).Image (or
anywhere else) simply by using BitBlt and specifying the location and size
of the desired "cell" of the composite picture box in the BitBlt parameters.
Otherwise, as has already been suggested by Larry, you can use a PictureClip
control. There are lots of different ways of doing these kind of things but
it isn't really possible to suggest the most appropriate method for your own
purposes until we know exactly what task you are performing. Perhaps you
might like to post again with further details.

Mike
Author
21 May 2009 6:44 PM
caver_dave
Show quote Hide quote
"Mike Williams" wrote:

> "caver_dave" <caverd***@discussions.microsoft.com> wrote in message
> news:A54128D2-15D7-4CFA-A449-DCC1D9223320@microsoft.com...
>
>  >I have a small app that writes an array of pic boxes to a
> > picbox in order to save it as a bitmap
> > *sample code for one line *
> > Picture5.PaintPicture Picture1(0).Image, 0, 0, 1, 1
> > Picture5.PaintPicture Picture1(1).Image, 1, 0, 1, 1
> > . . . . . I am not sure how to go about doing the reverse
> > Picture1(0).Picture = Picture5.Picture,0, 0, 1, 1
>
> It depends on whether your code (extract above) is drawing the original
> Image into the "composite" Picture Box at the full Picture1(n).Image size or
> whether it is reducing it to a thumbnail (it isn't possible to tell for
> certain what you are doing simply by looking at your example code). If you
> are drawing into the composite PicBox as a smaller thumbnail of the Image
> then you cannot get back the original Image from the "composite thumbnail"
> alone without a great loss of quality. In other words, you cannot expand the
> thumbnail's size by stretching the thumbnail without the result becoming
> "blocky". However I suspect that you are drawing into the composite at the
> original Picture1(n).Image size, in which case you can get the appropriate
> section of the composite back into the original Picture1(n).Image (or
> anywhere else) simply by using BitBlt and specifying the location and size
> of the desired "cell" of the composite picture box in the BitBlt parameters.
> Otherwise, as has already been suggested by Larry, you can use a PictureClip
> control. There are lots of different ways of doing these kind of things but
> it isn't really possible to suggest the most appropriate method for your own
> purposes until we know exactly what task you are performing. Perhaps you
> might like to post again with further details.
>
> Mike
>
>  Thanks to all for your help

Mike
the idea is to writ e a 10 x 10 px bitmap into a much larger grid so that it
can be edited. Being blocky at that stage does not matter as only the 10 x 10
preview picture is saved.
I think that using the picture clip control is the way to go, thanks LFS for
reminding me ;-), for ease of use if nothing else.
To Bee thanks im sure it will come in handy
regards
Show quoteHide quote
>
Author
21 May 2009 8:20 PM
Mike Williams
"caver_dave" <caverd***@discussions.microsoft.com> wrote in message
news:B1BCCAD9-04F3-44F3-854D-919E03B491C9@microsoft.com...

> Mike. The idea is to write a 10 x 10 px bitmap into a much
> larger grid so that it can be edited. Being blocky at that
> stage does not matter as only the 10 x 10 preview picture
> is saved.

Actually that sounds quite a bit different from your original description of
what you are doing. It would appear from your latest description that you
have a 10 x 10 pixel bitmap which you want to display at a much larger size
so that the user can more easily edit the colour of each individual pixel.
If that is the case then it would appear that you have just a single pixel
(or the representation of just a single pixel) in each of your array of 100
Picture boxes? Is that really what you've got?

If I have correctly understood your latest description then you can simply
load the 10 x 10 pixel bitmap into a small 10 x 10 pixel Autoredraw
pictureBox (so that this PictureBox displays the original 10 x 10 pixel
bitmap at its normal size) and then you can paint the Image from that
pictureBox into a larger PictureBox (for example 160 x 160 pixels) so that
the 10 x 10 pixel bitmap is displayed in the 160 x 160 pixel Autoredraw
PictureBox with each indicidual "pixel" being represented by a solid 16 x 16
pixel rectangle. In that way you will need a total of just two pictureBoxes,
rather than the array of 100 that you appear to be currently using, and
youwillo not need a PictureClip Control or anything else.

You can draw the "enlarged" image from the small 10 x 10 pixel Autoredraw
PictureBox into the larger 160 x 160 pixel Autoredraw pictureBox with a
single PaintPicture statement. These values by the way (10 x 10 and 160 x
160) are the size of the client area of each PictureBox, as I'm sure you
will alreayd know. For example, the following line should do what you want
(where in this examle Picture1 has a client area of 10 x 10 pixels and it
contains the 10 x 10 bitmap and Picture2 has a client area of 160 x 160
pixels, and with both PictureBoxes having Autoredraw True and ScaleMode of
vbPixels:

  Picture2.PaintPicture Picture1.Image, _
      0, 0, 160, 160, 0, 0, 10, 10, vbSrcCopy

You can then add code to the MouseDown (etc) events of Picture2 POictureBox
to allow the user to select a "pixel" and set it to whatever other colour he
desires. Then, when the user has completed his editting you can draw the
"large scale" 160 x 160 pixel Image from picture1 into either the original
10 x 10 pixel PictureBox or into some other small 10 x 10 pixel PictureBox
(Picture3 in this example) with another single call to PaintPicture,
something like:

  Picture3.PaintPicture Picture2.Image, _
      0, 0, 10, 10, 0, 0, 160, 160, vbSrcCopy

This will work fine both in the "increase size" and "reduce size" directions
because the VB PaintPicture Method always uses the DeleteScans stretch mode,
which is ideal for this purpose. However, if you decide for any reason to
use StretchBlt instead of the VB PaintPicture method then make sure you set
the StretchMode to DeleteScans, although on the assumption that you are
going to run this code on machines with their display set to either 16 bit
or 32 bit (which is almost certainly the case) then VB PictureBoxes and
PaintPicture should be fine for your purposes.

Unless of course I've misunderstood the latest description of what you are
doing, in which case please post again.

Mike
Author
21 May 2009 9:38 PM
Larry Serflaten
"caver_dave" <caverd***@discussions.microsoft.com> wrote

> the idea is to writ e a 10 x 10 px bitmap into a much larger grid so that it
> can be edited. Being blocky at that stage does not matter as only the 10 x 10
> preview picture is saved.
> I think that using the picture clip control is the way to go, thanks LFS for
> reminding me ;-), for ease of use if nothing else.
> To Bee thanks im sure it will come in handy

Now that you've explained it a bit further, I'd suggest a PictureClip control would
not be the best route.  What you want can easily be done using two pictureboxes.
For a quick example, add two pictureboxes to a new form and paste in the code
below.  Note that most of it is setup code, to position the two controls!

LFS

Option Explicit

Private Sub Form_Load()
  Me.ScaleMode = vbPixels
  With Picture1
    .BorderStyle = vbBSNone
    .Move 10, 10, 10, 10
    .BackColor = vbWhite
    .ScaleMode = vbPixels
  End With
  With Picture2
    .BorderStyle = vbBSNone
    .Move 10, 40, 100, 100
    .BackColor = vbWhite
    Picture2.Scale (0, 0)-(10, 10)
  End With
  Me.Move Me.Left, Me.Top, 3000, 3000
End Sub

Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  Draw X, Y, Button
End Sub

Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  Draw X, Y, Button
End Sub

Private Sub Picture2_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  Draw Int(X), Int(Y), Button
End Sub

Private Sub Picture2_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  Draw Int(X), Int(Y), Button
End Sub

Sub Draw(ByVal X As Long, ByVal Y As Long, ByVal Button As Long)
  Dim K As Long
  If Button Then
     K = vbWhite And (Button = vbRightButton)
     Picture1.PSet (X, Y), K
     Picture2.Line (X, Y)-Step(0.9, 0.9), K, BF
  End If
End Sub
Author
21 May 2009 7:12 PM
Rick Raisley
While the sample code seems a bit incomplete (needing to specify locations
within the larger picture to place the smaller ones), you should be able to
easily do all of this with PaintPicture. Look at the help on PaintPicture.
The x1, y1, width1, and height1 all refer to the target picture. It tells
PaintPicture where, in your larger picture, to place the images of the
smaller ones. x2, y2, width2, and height2 can often be ignored, as x2 = y2 =
0 is used, and width and height are assumed to be the entire size of the
picture being copied.

When going from the larger picture to several smaller ones, x1 and y1 will
normally be 0 (the upper left corner of the small picture), and width1 and
height1 will be the size of the smaller picture. But in this case, you WILL
use x2, y2, width2, and height2, to locate the upper left position, width
and height of the area of the larger picture to be copied. the operation is
exactly the same, you just switch around the parameters.

Please note that after doing the modifications on the larger picture, prior
to chopping it up into smaller ones, you may want to set largepic.picture =
largepic.image, or make sure you are copying the Image, rather than the
Picture.

While I've done all this, and it seems really simple to me, I must be really
missing something. When Larry points to using a different control or method
than this, it probably means I misunderstood your question. ;-)

--
Regards,

Rick Raisley
heavymetal-A-T-bellsouth-D-O-T-net

Show quoteHide quote
"caver_dave" <caverd***@discussions.microsoft.com> wrote in message
news:A54128D2-15D7-4CFA-A449-DCC1D9223320@microsoft.com...
>I have a small app that writes an array of pic boxes to a picbox in order
>to
> save it as a bitmap
> *sample code for one line *
> Picture5.PaintPicture Picture1(0).Image, 0, 0, 1, 1
> Picture5.PaintPicture Picture1(1).Image, 1, 0, 1, 1
> Picture5.PaintPicture Picture1(2).Image, 2, 0, 1, 1
> Picture5.PaintPicture Picture1(3).Image, 3, 0, 1, 1
> Picture5.PaintPicture Picture1(4).Image, 4, 0, 1, 1
> Picture5.PaintPicture Picture1(5).Image, 5, 0, 1, 1
> Picture5.PaintPicture Picture1(6).Image, 6, 0, 1, 1
> Picture5.PaintPicture Picture1(7).Image, 7, 0, 1, 1
> Picture5.PaintPicture Picture1(8).Image, 8, 0, 1, 1
> Picture5.PaintPicture Picture1(9).Image, 9, 0, 1, 1
> * the other lines follow suit *
>
> I am not sure how to go about doing the reverse
>
> Picture1(0).Picture = Picture5.Picture,0, 0, 1, 1
>
> i know that this is not correct
> any help with my problem would be greatly appreciated
>
> Thanks in advance
>
>
>
Author
23 May 2009 7:34 PM
caver_dave
To all those that have helped again

Mike, Rick and Larry, thanks for your ideas and suggestions I will be trying
them all as I rewite my app to work more effectively

many thanks

dave

Show quoteHide quote
"Rick Raisley" wrote:

> While the sample code seems a bit incomplete (needing to specify locations
> within the larger picture to place the smaller ones), you should be able to
> easily do all of this with PaintPicture. Look at the help on PaintPicture.
> The x1, y1, width1, and height1 all refer to the target picture. It tells
> PaintPicture where, in your larger picture, to place the images of the
> smaller ones. x2, y2, width2, and height2 can often be ignored, as x2 = y2 =
> 0 is used, and width and height are assumed to be the entire size of the
> picture being copied.
>
> When going from the larger picture to several smaller ones, x1 and y1 will
> normally be 0 (the upper left corner of the small picture), and width1 and
> height1 will be the size of the smaller picture. But in this case, you WILL
> use x2, y2, width2, and height2, to locate the upper left position, width
> and height of the area of the larger picture to be copied. the operation is
> exactly the same, you just switch around the parameters.
>
> Please note that after doing the modifications on the larger picture, prior
> to chopping it up into smaller ones, you may want to set largepic.picture =
> largepic.image, or make sure you are copying the Image, rather than the
> Picture.
>
> While I've done all this, and it seems really simple to me, I must be really
> missing something. When Larry points to using a different control or method
> than this, it probably means I misunderstood your question. ;-)
>
> --
> Regards,
>
> Rick Raisley
> heavymetal-A-T-bellsouth-D-O-T-net
>
> "caver_dave" <caverd***@discussions.microsoft.com> wrote in message
> news:A54128D2-15D7-4CFA-A449-DCC1D9223320@microsoft.com...
> >I have a small app that writes an array of pic boxes to a picbox in order
> >to
> > save it as a bitmap
> > *sample code for one line *
> > Picture5.PaintPicture Picture1(0).Image, 0, 0, 1, 1
> > Picture5.PaintPicture Picture1(1).Image, 1, 0, 1, 1
> > Picture5.PaintPicture Picture1(2).Image, 2, 0, 1, 1
> > Picture5.PaintPicture Picture1(3).Image, 3, 0, 1, 1
> > Picture5.PaintPicture Picture1(4).Image, 4, 0, 1, 1
> > Picture5.PaintPicture Picture1(5).Image, 5, 0, 1, 1
> > Picture5.PaintPicture Picture1(6).Image, 6, 0, 1, 1
> > Picture5.PaintPicture Picture1(7).Image, 7, 0, 1, 1
> > Picture5.PaintPicture Picture1(8).Image, 8, 0, 1, 1
> > Picture5.PaintPicture Picture1(9).Image, 9, 0, 1, 1
> > * the other lines follow suit *
> >
> > I am not sure how to go about doing the reverse
> >
> > Picture1(0).Picture = Picture5.Picture,0, 0, 1, 1
> >
> > i know that this is not correct
> > any help with my problem would be greatly appreciated
> >
> > Thanks in advance
> >
> >
> >
>
>
>