region filled with bitmap/image
region filled with bitmap/image
region filled with bitmap/image
region filled with bitmap/image
region filled with bitmap/image
region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image
region filled with bitmap/image region filled with bitmap/image
region filled with bitmap/image
Go Back  Xtreme Visual Basic Talk > > > region filled with bitmap/image


Reply
 
Thread Tools Display Modes
  #1  
Old 01-05-2012, 07:39 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default region filled with bitmap/image


What i'm trying to do is fill a non rectangular region (actual build up out of 6 points) and draw a bitmap in such a way that it stretches with the region. Now for drawing a normal bitmap or even a trapezoid bitmap there are examples on the net. but drawing anything more then that with GDI+....

Hope anybody can help me out here
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #2  
Old 01-05-2012, 01:10 PM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default Fill polygon region with stretched bitmap texture

When you say you are creating a region from points are you using something like this code?

I'm thinking instead you might create the graphic in such a way to define the shape, basically clipping the texture into a region/polygon with a defined color like this.

If your points define a hexagon the picturebox shaping code is in this thread.

If you wish to go the "Graphics.DrawPolygon, Graphics.FillPolygon, Texturebrush" route you might also find this helpful.

If you need to let the user define the area/shape at runtime (with a mousedown event creating the points), then this might be the way to go.

The only difficulty I could see is in the dynamic stretching/resizing at runtime.
As noted in the last post of this thread, you may have to use PictureBox.Region.Dispose() before setting the region, if the shape is going to be transformed at runtime.

If this is going down the WPF/Xaml road you might need more help than I can give.
...but in the "Painting with Images" section (scroll down the page a ways from the starting "WPF Imaging Component" section) of this MSDN Imaging Overview, they recommend using the ImageBrush (a type of TileBrush which has a Stretch property).
The article also talks about clipping using a specific clipgeometry, so this Geometry Overview might be useful to scan over if you want to go that route.

Last edited by surfR2911; 01-05-2012 at 02:33 PM.
Reply With Quote
  #3  
Old 01-05-2012, 04:14 PM
AtmaWeapon's Avatar
AtmaWeaponregion filled with bitmap/image AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

I think the difficulty depends on what you mean by "stretched across the polygon".

One way to interpret this requirement: draw a bounding box around the polygon, stretch the bitmap across that bounding box, then let the image "poke through" the polygon. Probably possible, but I haven't given any thought to what it'd look like.

The harder way to interpret the requirement: you want to "attach" the points of the polygon to parts of the bitmap, then have the image stretch in all directions. This is like you had pinned an elastic cloth to the edges of some shape. I think you need to do manual image manipulation to pull this off in Windows Forms. Even in WPF I'm not entirely sure if it's easy. My first guess in WPF would be to use WPF 3D: create a mesh that represents the polygon and use the image as a texture. Still, it's sufficiently advanced I'm not sure I could produce a workable example.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #4  
Old 01-06-2012, 04:40 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default

ofcourse the last senario you scetched is what i want ...
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #5  
Old 01-06-2012, 02:19 PM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default WPF ViewPort3D MeshGeometry3D ModelVisual3D Point3D TriangleIndices

What AtmaWeapon is talking about - working with meshes (usually 3D with a 2D viewport) in WPF is an order of magnitude more involved than the 2D only approach (Transform TextureBrush FillPolygon) I was hinting at earlier.

I too must admit extreme humility when it comes to developing a working example for such an advanced topic.

I can tell you this (from having spent many an hour cruising the MSDN for WPF articles) - most of the code samples are written in c# rather than VB.Net, but I will endeavor to provide some (useful?)(relevant?) links.

Here is a cool picture of what it looks like to wrap a texture around a cylinder using xaml. It's from Charles Petzold's Foundations of 3D Mesh Geometries article.

Of course the somewhat advanced code for that article is written in C#,
so let's take a take a step back and start from the beginning of things
(just in case your WPF knowledge is not altogether at the expert level):
Introduction to WPF (MSDN)
3-D Graphics Overview (MSDN)
WPF 3D Primer (MSDN)
WPF Wonders: 3D Drawing
3D model in WPF
WPF 3D (pdf) - pages 26-31 are on texture mapping
How to manipulate a 3D mesh in WPF (off forum MSDN thread)
Create 3D Triangle (off forum MSDN thread)

All of which should get you up to speed to deal with such topics as:
-GeometryModel3D with MeshGeometry3D
-GeometryModel3D Geometry Material
-Drawing a 3D Model

..the WPF code for which is available off this page.

It's a lot of Xaml code to go through,
so here's a summary (bare bones) of the steps involved:
1.) Declare scene object
2.) Specify where in the 3D scene the camera is
3.) Specify the direction that the camera is pointing
4.) Define camera's horizontal field of view in degrees
5.) Assign the camera to the viewport
6.) Define the lights cast in the scene.
(Without light, the 3D object cannot be seen)
7.) Define the mesh geometry, specifying the shape
(usually a flat sheet) of the 3D plane
8.) Create a collection of normal vectors for the MeshGeometry3D
9.) Create a collection of vertex positions (3D points)
for the MeshGeometry3D
10.) Create a collection of texture coordinates for the MeshGeometry3D
11.) Create a collection of triangle indices for the MeshGeometry3D
12.) Apply the mesh to the geometry model
13.) Define material and apply to the mesh geometries
14.) Apply a transform to the object (if needed)
15.) Add the geometry model to the model group
16.) Add the model (or group of models) to the ModelVisual3d.
17.) Apply the viewport to the page so it will be rendered
Simple, huh?
Here's an MSDN page on setting up a basic 3D scene with some commented code.

There's also the skinned mesh approach.
I hate to even mention it, but the steps are markedly different.
This TigerTexture code (C#, sorry) should give you an idea of that different approach.

Oh and I hate to put all those links and not a single working sample,
so here is VB.Net/XAML Spinning Cube
(yeah I know its not the texture image stretched over
mesh filled polygon example but its a working stating point..)

Last edited by surfR2911; 01-06-2012 at 04:11 PM.
Reply With Quote
  #6  
Old 01-09-2012, 08:57 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default thanks

Thank you very much VB6Oldguy and AtmaWeapon for your insights..
From what i have researched so far i think i need to use a technique called bilinear interpolation.
This will be compleetly new for me so not sure how far i will go before getting stuck :P
I have found this example http://www.codeproject.com/KB/GDI-plus/ImageWarp.aspx, to help me on my way.
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #7  
Old 01-17-2012, 01:26 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default ok... so far...

ok this is what i have so far...
this code will distort a image with a "fisheye" effect...
Aldo it isn't fast enough for me yet.. does any one see a possibility to speed it up?



Code:
    ''' <summary>
    ''' Ru = Rd(1+k*Rd^2)
    ''' ----------------------------------Wiki-----------------------------------------------------
    ''' Radial distortion, whilst primarily dominated by low order radial components,[1] can be corrected using Brown's distortion model.[2] Brown's model caters for both radial distortion and for tangential distortion caused by physical elements in a lens not being perfectly aligned. The latter is thus also known as decentering distortion.
    ''' xu = xd + (xd − xc)(K1r^2 + K2r^4 + ...) + (P1(r^2 + 2(xd − xc)^2) + 2P2(xd − xc)(yd − yc))(1 + P3r^2 + ...)
    ''' yu = yd + (yd − yc)(K1r^2 + K2r^4 + ...) + (P2(r^2 + 2(yd − yc)^2) + 2P1(xd − xc)(yd − yc))(1 + P3r^2 + ...)
    '''
    ''' where:
    '''
    ''' (xu,yu) = undistorted image point,
    ''' (xd,yd) = distorted image point,
    ''' (xc,yc) = distortion center (assumed to be the principal point),
    ''' Kn = nth radial distortion coefficient,
    ''' Pn = nth tangential distortion coefficient,
    ''' r = sqrt((xd-xc)^2 + (yd-yc)^2), and
    ''' ... = an infinite series. 
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub DistordBmp()

        Dim CenterOfDistortion As New System.Drawing.Point(m_Bmp.Width * 0.5, m_Bmp.Height * (m_CenterHeight / m_Bmp.Height))
        Dim NewP As System.Drawing.Point
        Dim LengthCenterToCurrentPixel As System.Drawing.Point
        Dim R As Double
        Dim Rd As Double
        Dim Fraction As Double
        ' Pixel offsets
        Dim OldOffset As Integer
        Dim NewOffset As Integer
        ' Lock the bitmap's bits.  
        m_BmpData = Bmp.LockBits(New System.Drawing.Rectangle(0, 0, m_Bmp.Width, m_Bmp.Height), _
                                 Drawing.Imaging.ImageLockMode.ReadWrite, _
                                 m_Bmp.PixelFormat)
        ' Get the address of the first line.
        m_IntPtrFirstLine = m_BmpData.Scan0
        ' Declare an array to hold the bytes of the bitmap.
        ' This code is specific to a bitmap with 24 bits per pixels.
        m_Bytes = m_BmpData.Stride * Bmp.Height
        ReDim m_RGBValues(m_Bytes - 1)
        ' Make all pixels white.
        ReDim m_NewRGBValues(m_Bytes - 1)
        For I As Integer = 0 To m_Bytes - 1
            m_NewRGBValues(I) = 255
        Next
        ' Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(m_IntPtrFirstLine, m_RGBValues, 0, m_Bytes)
        '
        For CurrentBitmapPixelX As Integer = 0 To m_Bmp.Width - 1
            For CurrentBitmapPixelY As Integer = 0 To m_Bmp.Height - 1
                '
                LengthCenterToCurrentPixel.X = (CurrentBitmapPixelX - CenterOfDistortion.X)
                LengthCenterToCurrentPixel.Y = (CurrentBitmapPixelY - CenterOfDistortion.Y)
                '
                R = (LengthCenterToCurrentPixel.X ^ 2 + LengthCenterToCurrentPixel.Y ^ 2) ^ 0.5
                ' Because we can devide by zero, we have to check this.
                If R <> 0 Then
                    '
                    Rd = R * (1 + (0.0001 * R ^ 2) + (0.00000001 * R ^ 4))
                    ' Determine the x,y position. the fraction is determind by Rd/R
                    Fraction = Rd / R
                    NewP.X = (LengthCenterToCurrentPixel.X * Fraction) + CenterOfDistortion.X
                    NewP.Y = (LengthCenterToCurrentPixel.Y * Fraction) + CenterOfDistortion.Y
                    ' Check if the new position is within the borders of the old bitmap.
                    If NewP.X >= 0 AndAlso NewP.X < m_Bmp.Width AndAlso NewP.Y >= 0 AndAlso NewP.Y < m_Bmp.Height Then
                        ' GDI+ still lies to us, the return format is BGR NOT RGB
                        ' Get the offset of the old pixel
                        OldOffset = m_BmpData.Stride * CurrentBitmapPixelY + (CurrentBitmapPixelX * 3)
                        ' Get the offset of the new pixel
                        NewOffset = NewP.Y * m_BmpData.Stride + NewP.X * 3
                        ' Get the color of the old pixel and set the new pixel
                        m_NewRGBValues(NewOffset) = m_RGBValues(OldOffset)
                        m_NewRGBValues(NewOffset + 1) = m_RGBValues(OldOffset + 1)
                        m_NewRGBValues(NewOffset + 2) = m_RGBValues(OldOffset + 2)
                    End If
                End If
            Next
        Next
        '
        'For k As Integer = 0 To 9
        For I As Integer = 3 To m_NewRGBValues.Length - m_BmpData.Stride - 4
            m_NewRGBValues(I) = BilinearInterpolation({m_NewRGBValues(I - 3), _
                                                       m_NewRGBValues(I + 3), _
                                                       m_NewRGBValues(I + m_BmpData.Stride - 3), _
                                                       m_NewRGBValues(I + m_BmpData.Stride + 3)})
        Next
        'Next
        ' Copy the RGB values back to the bitmap
        System.Runtime.InteropServices.Marshal.Copy(m_NewRGBValues, 0, m_IntPtrFirstLine, m_Bytes)
        ' Unlock the bits.
        m_Bmp.UnlockBits(m_BmpData)

    End Sub
    ''' <summary>
    ''' Takes 4 values, and calculates the value of the point smack bang in the middle
    ''' of those 4 values.
    ''' </summary>
    ''' <param name="RGBValues"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function BilinearInterpolation(ByRef RGBValues() As Integer) As Byte
        If RGBValues.Count = 4 Then
            Dim Diff_01 As Double = (RGBValues(0) + RGBValues(1)) * 0.5
            Dim Diff_02 As Double = (RGBValues(2) + RGBValues(3)) * 0.5
            Return CByte(0.5 * Diff_01 + 0.5 * Diff_02)
        Else
            Return 0
        End If
    End Function
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #8  
Old 01-19-2012, 05:02 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default Bilinear Interpolation, fast pixel access, and multi-core concurrency/parallelism

Quote:
i need to use a technique called bilinear interpolation
Now we are finally getting around to what you really need.

I don't know if this code is faster but there already exists a VB.Net sample for bilinear interpolation:
http://www.vb-helper.com/howto_net_warp.html

Did you know that System.Drawing.Drawing2D has both Bilinear and HighQualityBilinear interplation:
http://msdn.microsoft.com/en-us/libr...ationmode.aspx

There's some sample code for using Drawing2D.InterpolationMode.HighQualityBilinear on these dreamincode pages (1, 2).
Of course these interpolations are mainly for resizing not distorting/warping images.

So there is an general article about fast pixel manipulation in VB.Net here (which may help with performance).
This article might be applicable to vb.net(?):
Fast Pointerless Image Processing in .NET
Related article:
Pointers and Unmanaged Memory Handling in VB.NET

But no matter how fast/directly you can access the pixels, if you do a lot of math it's going to slow things down.
So if you want to stick with the lockbits code you have finding a way to limit the number of calculations.
That will probably be the key to improving performance.

The only other way I can think to to improve performance is to go parallel,
chunking up the calculations among multiple cores,
(maybe having each work on a section of pixels).

Here' some as article:
Getting Started with the .NET Task Parallel Library
Here is the part of the MSDN that deals with concurrency.
The pixel filter working sample mentioned in the article can be found here.

Last edited by surfR2911; 01-19-2012 at 05:39 AM.
Reply With Quote
  #9  
Old 01-24-2012, 02:04 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default Progress so far

I attached the progress so far, The distortion speed is good.. the routine is running for a 128 x 128 bitmap around about 0.01 second.... but i still having problems with the implementation of the bilinear interpolation, if any one would take a look... and tell my where my thinking mistakes are... thanks
Attached Files
File Type: zip BilinearInterpolationTest.zip (52.4 KB, 36 views)
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #10  
Old 01-24-2012, 04:33 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default Fixing?

Quote:
...but i still having problems with the implementation of the bilinear interpolation, if any one would take a look...
Just to clarify..I'm assuming this has to do with the white-ish lines appear in the attached screenshot.

It's a neat effect (sort of a cross between a moire and a guilloche pattern),
but I'm guessing it's an unwanted side-effect by your "ToDo" comment
in the DistordBmp (maybe should be DistortBmp) sub:
Quote:
Fill the pixel in between -the idea is if a new pixel is more then one pixel over, fill in the gap in between the old and the new. (one pixel = 3 bytes ... R,G,B).
By the way - I'm sure its a stupid thing (since I think you can set the form to center screen in the form's properties), but I had an old snippet that still seems to work when in VB.Net 2010 when dumped in the Form Load;
Code:
        ''Centers the form
        Dim mainScreen As Screen = Screen.FromPoint(Me.Location)
        Dim X As Integer = (mainScreen.WorkingArea.Width - Me.Width) / 2 + mainScreen.WorkingArea.Left
        Dim Y As Integer = (mainScreen.WorkingArea.Height - Me.Height) / 2 + mainScreen.WorkingArea.Top
        Me.StartPosition = FormStartPosition.Manual
        Me.Location = New System.Drawing.Point(X, Y)
Also - I thought (assumes) your "wiki" comments in post #7 where from a Wikipedia page --maybe for some Bilinear Interpolation entry, but the comments & equation actually come from the Software Correction section of the Distortion page.
Thus, conceivably (if working), it could be adapted to un-distort the image/video frames taken with a fish-eye lens.
metatags: radial distortion barrel distortion pincushion distortion

Edit:
The gaps are actually formed because in the process of expanding/distorting/warping the image you are actually injecting additional data (pixels) that were not in the original image.
I don't thing using higher order polynomials or a Fourier Space smoothing filter would help. It's probably best researched as an anti-aliasing issue.

Last edited by surfR2911; 01-24-2012 at 05:36 AM.
Reply With Quote
  #11  
Old 01-24-2012, 04:41 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 670
Default

thank you for your time VB6Oldguy
Your absolutely rite, the white lines are the problem.
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help
Reply With Quote
  #12  
Old 01-24-2012, 05:31 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default more research reveals..

Did you actually look at the VBHelper .Net Warp Images code I cited earlier?

The TransformImage sub includes code for calculating/computing the weighted average (color) based on surrounding pixels.

In case that isn't enough I did a little more research.

I learned that a GraphicsPath object has a Warp method as shown in this vbHelper Captcha code example.

Of course there is no free lunch.
It has a path flattening anomalies.
This article explains why and gives the code for a CuredWrap() function (involving subpaths) as part of
a QWarper class (C++ code - sorry, but maybe can be converted or give you some ideas - would need to be adapted for three point warping).
I agree with the author's assessment..
Quote:
Entering things like 'bilinear warp algorithm' in Google gave me hundreds of hits, but I couldn't find any off-the-shelf algorithm.
The only useful bits of information I found were the so-called warping functions for bilinear and perspective warping (and for a few other warping modes, as well).
I used these to devise my own algorithm.
Because it has been a while since I was in math class, and my calculus is a bit rusty, this was no easy exercise.
It involved tasks such as solving a set of eight equations with eight unknowns.
But, the very rewarding result is here: the QWarper class.
..it is no easy exercise.

Last edited by surfR2911; 01-24-2012 at 05:37 AM.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
region filled with bitmap/image
region filled with bitmap/image
region filled with bitmap/image region filled with bitmap/image
region filled with bitmap/image
region filled with bitmap/image
region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image region filled with bitmap/image
region filled with bitmap/image
region filled with bitmap/image
 
region filled with bitmap/image
region filled with bitmap/image
 
-->