Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Peter Fa » Tue, 01 Jul 2003 17:38:31



VB Picture boxes cannot display huge bitmaps esp if autoredraw is true.

I am using loadpicture to display images (jpg bmp) on an invisible
picturebox  before using paintpicture to display these on a visible smaller
picture box.

I can read the dimensions of the picture before attempting the above.

Is there any easy way of reducing the size of the huge bitmaps *prior* to
using loadpicture.

I am familiar with Graphics API.

Any pointers to a way of achieving this appreciated

Peter

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Larry Serflate » Tue, 01 Jul 2003 18:04:06



Quote:> VB Picture boxes cannot display huge bitmaps esp if autoredraw is true.

> I am using loadpicture to display images (jpg bmp) on an invisible
> picturebox  before using paintpicture to display these on a visible smaller
> picture box.

> I can read the dimensions of the picture before attempting the above.

> Is there any easy way of reducing the size of the huge bitmaps *prior* to
> using loadpicture.

> I am familiar with Graphics API.

> Any pointers to a way of achieving this appreciated

I would be interested to know if this handles your large pictures:

http://groups.google.com/groups?selm=%23n5RfIaODHA.1072%40TK2MSFTNGP1...

LFS

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Mike D Sutto » Tue, 01 Jul 2003 19:12:41


> VB Picture boxes cannot display huge bitmaps esp if autoredraw is true.

> I am using loadpicture to display images (jpg bmp) on an invisible
> picturebox  before using paintpicture to display these on a visible
smaller
> picture box.

> I can read the dimensions of the picture before attempting the above.

> Is there any easy way of reducing the size of the huge bitmaps *prior* to
> using loadpicture.

> I am familiar with Graphics API.

Not really, all of the image loading functions will only load the images at
their original size.  It is possible to write your own bespoke bitmap
reading routine which will only read a section or sample of the image but
you will only be able to get very low quality scaling from this (I.e. the
equivalent of COLORONCOLOR StretchBlt() mode.) since performing sampling on
the dataset will mean you have to load the entire image from disk
regardless.
Here's a method that will read an uncompressed True/High colour bitmap off
disk (Paletted images are left as an 'exercise for the reader', but are
dealt with in much the same way.  Compressed images can not be dealt with in
this way at all though, even RLE methods would have problems since they can
include delta scans.)

'***
Option Explicit

Private Declare Sub RtlMoveMemory Lib "kernel32" _
    (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function CreateDIBSection Lib "gdi32" _
    (ByVal hDC As Long, ByRef pBitmapInfo As BitmapInfoHeader, _
    ByVal un As Long, ByRef lplpVoid As Long, ByVal handle As Long, _
    ByVal dw As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
    (ByVal hObject As Long) As Long
Private Declare Function SelectObject Lib "gdi32" _
    (ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" _
    (ByVal hDC As Long) As Long
Private Declare Function BitBlt Lib "gdi32" ( _
    ByVal hDestDC 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 dwRop As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" _
    (ByVal hDC As Long) As Long
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" ( _
    ByVal hObject As Long, ByVal nCount As Long, _
    ByRef lpObject As Any) As Long

Private Type Bitmap ' 24 bytes
    bmType As Long
    bmWidth As Long
    bmHeight As Long
    bmWidthBytes As Long
    bmPlanes As Integer
    bmBitsPixel As Integer
    bmBits As Long
End Type

Private Type BitmapFileHeader
    bfType As Integer
    bfSize As Long
    bfReserved1 As Integer
    bfReserved2 As Integer
    bfOffBits As Long
End Type

Private Type BitmapInfoHeader ' 40 bytes
    biSize As Long
    biWidth As Long
    biHeight As Long
    biPlanes As Integer
    biBitCount As Integer
    biCompression As Long
    biSizeImage As Long
    biXPelsPerMeter As Long
    biYPelsPerMeter As Long
    biClrUsed As Long
    biClrImportant As Long
End Type

Private Const BI_RGB As Long = &H0

Private Sub Form_Load()
    Dim MyDIB As Long, OldDIB As Long
    Dim BMScale As Bitmap
    Dim MyDC As Long

    ' The first parameter is the filename to read
    ' The second is the pixel step i.e:
    '    1 = 100%
    '    2 = 50%
    '    3 = 33%
    '    4 = 25%
    '    etc...
    MyDIB = LoadBitmapSmall(SET BITMAP PATH HERE, 2)
    If (MyDIB) Then
        Call GetObjectAPI(MyDIB, Len(BMScale), BMScale)

        ' Temp, just for testing - Never do this in a 'real' app!
        Form1.AutoRedraw = True

        MyDC = CreateCompatibleDC(0)
        OldDIB = SelectObject(MyDC, MyDIB)
        Call BitBlt(Form1.hDC(), 0, 0, BMScale.bmWidth, _
            BMScale.bmHeight, MyDC, 0, 0, vbSrcCopy)
        Call DeleteObject(SelectObject(MyDC, OldDIB))
        Call DeleteDC(MyDC)
    Else
        Debug.Print "Error loading Bitmap..."
    End If
End Sub

Private Function LoadBitmapSmall(ByVal inName As String, _
    Optional ByVal inStep As Long = 1) As Long
    Dim BMFile As BitmapFileHeader
    Dim BMInfo As BitmapInfoHeader
    Dim FNum As Integer
    Dim DIBInfo As BitmapInfoHeader
    Dim BMScan As Long, DIBScan As Long
    Dim DIBData() As Byte
    Dim LoopX As Long, LoopY As Long
    Dim XPos As Long, YPos As Long
    Dim XStep As Long, BPP As Byte
    Dim DataOffset As Long
    Dim DataPtr As Long

    If (inStep < 1) Then Exit Function
    If (Not FileExist(inName)) Then Exit Function

    FNum = FreeFile()
    Open inName For Binary Access Read Lock Write As #FNum
        Get #FNum, , BMFile

        If (BMFile.bfType <> &H4D42) Then
            Debug.Print "File header does not match!"
            Close #FNum
            Exit Function
        End If

        Get #FNum, , BMInfo

        ' Validate header
        If ((BMInfo.biBitCount < 16) Or _
            (BMInfo.biCompression <> BI_RGB) Or _
            (BMInfo.biPlanes <> 1) Or _
            (BMInfo.biSize <> Len(BMInfo)) Or _
            (BMInfo.biWidth < inStep) Or _
            (BMInfo.biHeight < inStep)) Then
            ' Don't accept anything with a palette or compression,
            '   and a height or width less than the pixel step
            Debug.Print "Unsupported Bitmap format"
            Close #FNum
            Exit Function
        End If

        With DIBInfo
            .biSize = Len(DIBInfo)
            .biHeight = BMInfo.biHeight \ inStep
            .biWidth = BMInfo.biWidth \ inStep
            .biBitCount = BMInfo.biBitCount
            .biPlanes = 1
        End With

        LoadBitmapSmall = CreateDIBSection(0, DIBInfo, 0, DataPtr, 0, 0)
        If (LoadBitmapSmall = 0) Then ' Couldn't create DIBSection
            Debug.Print "Error createing DIBSection"
            Close #FNum
            Exit Function
        End If

        ' How many bytes per pixel?
        BPP = BMInfo.biBitCount \ 8

        ' How many bytes to we step from the source data
        XStep = BPP * inStep

        ' Get the scanline widths
        BMScan = GetScanWidth(BMInfo)
        DIBScan = GetScanWidth(DIBInfo)

        ' Get the offset to the start of the data
        DataOffset = Seek(FNum)

        ReDim DIBData(DIBScan - 1, DIBInfo.biHeight - 1) As Byte

        ' Step through the bitmap and write scampled pixels
        For LoopY = 0 To DIBInfo.biHeight - 1
            XPos = 0

            For LoopX = 0 To DIBInfo.biWidth - 1
                ' Offset and read this pixel
                Seek #FNum, DataOffset + XPos
                Call ReadBytesTo(FNum, BPP, _
                    ByVal VarPtr(DIBData(LoopX * BPP, LoopY)))
                XPos = XPos + XStep
            Next LoopX

            DataOffset = DataOffset + (BMScan * inStep)
        Next LoopY

        ' Copy the data into the DIBSection
        Call RtlMoveMemory(ByVal DataPtr, _
            DIBData(0, 0), DIBScan * DIBInfo.biHeight)
    Close #FNum
End Function

Private Sub ReadBytesTo(ByVal inNum As Integer, _
    ByVal inCount As Long, ByVal inAddr As Long)
    Dim Bytes() As Byte

    If (inCount < 0) Then Exit Sub

    ReDim Bytes(inCount - 1) As Byte

    Get #inNum, , Bytes()
    Call RtlMoveMemory(ByVal inAddr, Bytes(0), inCount)
End Sub

Private Function FileExist(ByVal inFile As String) As Boolean
    On Error Resume Next
    FileExist = CBool(FileLen(inFile) + 1)
End Function

Private Function GetScanWidth(ByRef inInfo As BitmapInfoHeader) As Long
    GetScanWidth = (RoundUp(inInfo.biWidth * _
        (inInfo.biBitCount / 8)) + 3) And &H7FFFFFFC
End Function

Private Function RoundUp(ByVal inVal As Single) As Long
    RoundUp = Int(inVal)
    If (inVal <> RoundUp) Then RoundUp = RoundUp + Sgn(inVal)
End Function
'***

Hope this helps,

    Mike

 - Microsoft Visual Basic MVP -
E-Mail: ED...@mvps.org
WWW: Http://www.mvps.org/EDais/

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Peter Fa » Tue, 01 Jul 2003 19:45:32


Larry

Thanks for the suggestion but unfortunately:

A Trucolor 2550 * 3510 pixel BMP (XPPro 256Mb RAM) fails with Error 480
"Can't create AutoRedraw image"

Peter



> > VB Picture boxes cannot display huge bitmaps esp if autoredraw is true.

> > I am using loadpicture to display images (jpg bmp) on an invisible
> > picturebox  before using paintpicture to display these on a visible
smaller
> > picture box.

> > I can read the dimensions of the picture before attempting the above.

> > Is there any easy way of reducing the size of the huge bitmaps *prior*
to
> > using loadpicture.

> > I am familiar with Graphics API.

> > Any pointers to a way of achieving this appreciated

> I would be interested to know if this handles your large pictures:

http://groups.google.com/groups?selm=%23n5RfIaODHA.1072%40TK2MSFTNGP1...
bl&rnum=1

- Show quoted text -

Quote:

> LFS

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Peter Fa » Tue, 01 Jul 2003 20:13:55


Thanks Mike,

I would assume then that bitmaps in memory are not subject to the same
restrictions as those contained within pictureboxes.

For info,  EZTwain from dosadi contains functions which will retrieve a hDIB
from a file name (also includes tiff png jpg and gif).

I think I'll try loading hDIBs using these, SetDIBBits into a memory dc,
then StretchDIBBits to the picturebox

I'll report back accordingly

Peter

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Larry Serflate » Tue, 01 Jul 2003 20:23:44



Quote:> Not really, all of the image loading functions will only load the images at
> their original size.

Can you find out why stdole.StdFunctions.LoadPicture doesn't work?
I get Intellisence but the image comes in at its original size:

Ex:
Set Me.Picture = stdole.StdFunctions.LoadPicture("d:\temp\sml.bmp", Me.ScaleWidth, Me.ScaleHeight, Color)

Its like its all there except they did not implement the desired width/height functions.
Even *.wmf files are not effected by those 'desired' parameters.  What are they for?

That certainly would have made things significantly easier!

???
LFS

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Larry Serflate » Tue, 01 Jul 2003 20:40:41



Quote:> Larry

> Thanks for the suggestion but unfortunately:

> A Trucolor 2550 * 3510 pixel BMP (XPPro 256Mb RAM) fails with Error 480
> "Can't create AutoRedraw image"

Did you try a factor of .5 instead of leaving at it 4?
A factor of 4 is 4 times the original size, a factor of .5 is 1/2
How about a factor of .1 ???

LFS

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Mike D Sutto » Tue, 01 Jul 2003 20:56:04


Quote:> Can you find out why stdole.StdFunctions.LoadPicture doesn't work?
> I get Intellisence but the image comes in at its original size:

> Ex:
> Set Me.Picture = stdole.StdFunctions.LoadPicture("d:\temp\sml.bmp",

Me.ScaleWidth, Me.ScaleHeight, Color)
Quote:

> Its like its all there except they did not implement the desired

width/height functions.

Quote:> Even *.wmf files are not effected by those 'desired' parameters.  What are
they for?

> That certainly would have made things significantly easier!

It's probably just for icon's (Pass down from ExtractIcon() I'd imagine)
since a single icon file can have multiple images contained within it so it
needs to know which would be most suited to what's required - Only a
(Somewhat ;) educated guess though.

    Mike

 - Microsoft Visual Basic MVP -

WWW: Http://www.mvps.org/EDais/

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Larry Serflate » Tue, 01 Jul 2003 21:31:53



Quote:> > Can you find out why stdole.StdFunctions.LoadPicture doesn't work?
> > I get Intellisence but the image comes in at its original size:
> > That certainly would have made things significantly easier!

> It's probably just for icon's (Pass down from ExtractIcon() I'd imagine)
> since a single icon file can have multiple images contained within it so it
> needs to know which would be most suited to what's required - Only a
> (Somewhat ;) educated guess though.

You MVP's get a little better access than us 'regular folk'.  I was kinda
hoping you could float that question in your private newsgroup to see
if you get any takers.

Your 'ExtractIcon' suggestion seems a bit out there since there are no
such parameters to indicate size in the ExtractIcon function itself.  If
you meant ExtractIconEX, there is still only the Large or Small variety
without width or height options....

But, I have no better explaination and was looking to find more info.
MSDN comes up with only a few references about PowerPoint ....

LFS

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Mike D Sutto » Tue, 01 Jul 2003 22:05:35


Quote:> You MVP's get a little better access than us 'regular folk'.  I was kinda
> hoping you could float that question in your private newsgroup to see
> if you get any takers.

> Your 'ExtractIcon' suggestion seems a bit out there since there are no
> such parameters to indicate size in the ExtractIcon function itself.  If
> you meant ExtractIconEX, there is still only the Large or Small variety
> without width or height options....

Yup, ExtractIconEx() sorry.

Quote:> But, I have no better explaination and was looking to find more info.
> MSDN comes up with only a few references about PowerPoint ....

Just checked the doc's and it concurs:
http://msdn.microsoft.com/library/en-us/vb98/html/vbfctLoadPicture.asp

    Mike

 - Microsoft Visual Basic MVP -

WWW: Http://www.mvps.org/EDais/

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Larry Serflate » Tue, 01 Jul 2003 23:28:49



Quote:

> Just checked the doc's and it concurs:
> http://msdn.microsoft.com/library/en-us/vb98/html/vbfctLoadPicture.asp

That is the LoadPicture routine from the VB library.  The one I was mentioning
is from the stdole library.

Type:   stdole.LoadPicture(

Into the VB editor and you will not see the same parameters as the one from VB.

(It is available in VB5 anyway...)

LFS

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Peter Fa » Wed, 02 Jul 2003 00:49:19


Apologies Larry,

I had taken too quick a look at your code before replying!

With a factor of .1 even an 8500 * 11700 pixel image was successfully
loaded,  reduced and rewritten

Thanks for your help

Peter

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Peter Fa » Wed, 02 Jul 2003 23:34:31


Quote:> With a factor of .1 even an 8500 * 11700 pixel image was successfully
> loaded,  reduced and rewritten

The above applies to WinXP

WinNT freezes at loadpicture stage on files 5100 * 7020 pixels or greater -
still that's a significant improvement on 2100 * 2100 limitation

Peter

 
 
 

Shrink Huge Bitmaps ( > 2100 * 2100 pixels)

Post by Larry Serflate » Fri, 04 Jul 2003 05:37:13



Quote:> That is the LoadPicture routine from the VB library.  The one I was mentioning
> is from the stdole library.

Just to close out the thread, I found the stdole LoadPicture function was included
for future features and is not fully implemented.

The only MS reference I could find about it was archived info from 2001:

http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B268770

LFS

 
 
 

1. UMax 2100, VistaScan and CMYK

I have a UMax 2100U scanner connected to a bl&w G3, MacOS 8.6, which
uses the VistaScan 3.5.1 plug-In with Adobe Photoshop 4.0.

When I scan RGB or RGB 36-bit and print to our Xerox color printer,
everything gets this "blue cast" layer on top of the image. I'm
guessing I need to scan CMYK, but for some reason the option is greyed
out.

Anyone have an idea (either enabling CMYK or some VistaScan/Photoshop
settings) that can help me out?

Thanks.

Sent via Deja.com http://www.deja.com/
Before you buy.

2. Cerco gif animate

3. Edge-to-edge printing with Epson 2100/2200 in PSCS

4. Healing brush for PSP 8?

5. colours setting in PS7 for epson 2100 on a MAC

6. LW4

7. Gloria XL or E&S 2100

8. Looking for ".jpg" or ".gif"

9. DPS PAR DR-2100 Vs DPS PVR-2500?

10. Metafiles and wrong font on HP Laserjet 2100