Calling all web gurus: I need your help (CSS)

D

DotNetWebs

I have just done a little bit more:

http://dotnetwebs.com/test/imagegrid/

It will now fill the first row with random images.

It will then seek the first 'gap' and fill it with a random image chosen from those that will fit.

When I get time I will refine it to repeat this pattern to fill the rest of the grid (it already will but there are errors as I haven't put all the 'edge' detection in yet).

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
:) it is going to be interesting to see if it works with a limited image dimension set.

If you can always just choose something that fits, then it will tend to be a 1x1 at the end, the most flexible pieces.

I suppose you could mirror a bit to stop that consistency.

But I do think the problem is better done with two steps, that allows you to have patterns that will work rather than get into a potential infinite loop in real time, it also speeds things up and uses less processing over time, though you could store them up and use them to break an infinite.
 
Upvote 0
D

DotNetWebs

:) it is going to be interesting to see if it works with a limited image dimension set.

If you can always just choose something that fits, then it will tend to be a 1x1 at the end, the most flexible pieces...

There will be some ground rules. All images must have dimensions that are multiples of the base grid (currently 50px - this figure is a constant in the code and easily changed).


...But I do think the problem is better done with two steps, that allows you to have patterns that will work rather than get into a potential infinite loop in real time, it also speeds things up and uses less processing over time, though you could store them up and use them to break an infinite.

With efficient coding you won't get an infinite loop and it won't require much processing power. ASP.NET excels at this time of thing. You can use code-behind classes to produce an object-orientated model that reduces the problem to [relatively] simple steps.

TBH I have always preferred 'real-time' modeling and problem solving. It's a challenge to produce efficient code but need not require too many resources.

Have a look at this Flash model from my past:

http://dotnetwebs.com/wbt/Volume_and_Temperature.html

Each of the coloured dots represents air molecules [red o2 blue n2]. Each dot is a Flash object and moves in real-time, random motion. Each one has to work out the space around it before it moves. It's not that a dissimilar problem from the image grid but this was done over 7 years ago and runs in a Flash object in your browser.

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
It is the compromises you have to make in real time, it tends to make the solution a little less random, some patterns won't emerge because you will be locking off stuff.

But here is my offering that uses the assumption that any size image is available:

Just noticed a glitch :)

I used Numeric for a matrix, and then shoved in the heuristics to force fit stuff, kept the 1 x 1 to a minimum until the end where it just goes and plugs the gaps.
 
Last edited:
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
That was fun, I was going round checking off by 1s and all sorts, turned out to be the little matrix helper sum :)

Code:
#!/usr/bin/python

import random

from Numeric import *
#-----------------------------------------------------------

def main():
    """Create Grid Patern"""

    img_cols = 4
    img_rows = 4

    grid_cols = 20
    grid_rows =  7

    grid = zeros( ( grid_rows, grid_cols ) )

    print grid

    x = 0
    y = 0

    while 1:

        shape_cols = random.randint( 1, img_cols )

        if shape_cols == 1:
            shape_rows = random.randint( 2, img_rows )

        else:
            shape_rows = random.randint( 1, img_rows )

        x, y = add_img(
            grid, x, y, shape_cols, shape_rows )

        if ( y >= grid_rows ):
            break

    fill_remaining_zeroes( grid )

    print "\n-- Final Pattern --\n"

    print grid
#-----------------------------------------------------------

def fill_remaining_zeroes( grid ):
    """Fill Remaining Zeroes with 1 x 1"""

    for row, l in enumerate( grid ):
        for col, i in enumerate( l ):
            if i == 0:
                grid[ row, col ] = 11
#-----------------------------------------------------------

def add_img( grid, x, y, shape_cols, shape_rows ):
    """Add image to the Grid"""

    grid_rows, grid_cols = shape(grid)

    while 1:

        # guard
        if    shape_cols < 1 \
           or shape_rows < 1:
            return grid_cols, grid_rows

        id = int( str( shape_cols ) + str( shape_rows ) )

        print id

        x2 = x + shape_cols
        y2 = y + shape_rows

        if x2 > grid_cols:
            # reduce columns by 1
            shape_cols -= 1

        if y2 > grid_rows:
            # reduce rows by 1
            shape_rows -= 1

        if x2 > grid_cols or y2 > grid_rows:
            # shape was too large
            continue

        if sum( sum( grid[ y : y2, x : x2 ] ) ) == 0:
            # valid shape

            grid[ y : y2, x : x2 ] = id
            print grid

            # find next zero coord

            y2 = grid_rows

            for row, l in enumerate( grid ):
                for col, i in enumerate( l ):

                    if i == 0:

                        y2 = row
                        x2 = col
                        return x2, y2

        if shape_cols > 1:
            shape_cols -= 1
        else:
            shape_rows -= 1
#-----------------------------------------------------------

if __name__ == "__main__":
    main()
#-----------------------------------------------------------
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
Once one pattern is there you can get three more, flip, mirror and reverse.

Interestingly if you combine the transforms they create a previous effect :)

Code:
... snip

    print "\n-- Final Pattern --\n"

    print grid

    print "\n-- Flip Grid --\n"

    flip_grid = matrix_flip( grid )

    print flip_grid

    print "\n-- Mirror Grid --\n"

    mirror_grid = matrix_mirror( grid )

    print mirror_grid

    print "\n-- Reverse Grid --\n"

    reverse_grid = matrix_reverse( grid )

    print reverse_grid

    print "\n-- Flip Mirror Gird --\n"

    flip_mirror_grid = matrix_flip( mirror_grid )

    print flip_mirror_grid

    print "\n-- Reverse Flip Grid --\n"

    reverse_flip_grid = matrix_reverse( flip_grid )

    print reverse_flip_grid

    print "\n-- Reverse Mirror Grid --\n"

    reverse_mirror_grid = matrix_reverse( mirror_grid )

    print reverse_mirror_grid

    print "\n-- Reverse Flip Mirror Grid --\n"

    reverse_flip_grid = matrix_reverse( flip_mirror_grid )

    print reverse_flip_grid
#-----------------------------------------------------------

def matrix_flip( grid ):
    """Matrix Flip"""

    grid_rows, grid_cols = shape( grid )

    flip_grid = zeros ( shape( grid ) )

    k = 0
    for row in xrange( grid_rows - 1, -1, -1 ):
        flip_grid[ k ] = grid[ row ]
        k += 1

    return flip_grid
#-----------------------------------------------------------

def matrix_mirror( grid ):
    """Matrix Mirror"""

    grid_rows, grid_cols = shape( grid )

    mirror_grid = zeros ( shape( grid ) )

    k = 0
    for col in xrange( grid_cols -1, -1, -1 ):
        mirror_grid[ 0:,  k  ] \
            =  grid[ 0:, col ]
        k += 1

    return mirror_grid
#-----------------------------------------------------------

def matrix_reverse( grid ):
    """Matrix Reverse"""

    grid_rows, grid_cols = shape( grid )

    reverse_grid = zeros ( shape( grid ) )

    r = 0
    for row in xrange( grid_rows -1, -1, -1 ):
        c = 0
        for col in xrange( grid_cols -1, -1, -1):

            reverse_grid[ r, c ] = grid[ row, col ]
            c += 1

        r += 1

    return reverse_grid
#-----------------------------------------------------------

snip ...

The set of images is not really being considered though, and that would create a lot of checking inside the code, or you load up on a lot
of minimum sized images to plug the gap.

Batch pattern generation would also allow you to discard patterns that are perhaps too 1x1 like.

I was expecting to find more matrix transformation features in Numeric, they may be in there as well, that would reduce the volume of code a fair bit - it is 4.3K at the mo.
 
Upvote 0
It is the compromises you have to make in real time, it tends to make the solution a little less random, some patterns won't emerge because you will be locking off stuff...

I disagree - every pattern that is possible with these shapes is possible with this code.

The only 'comprise' is the allowable dimensions of the included shapes. These could be reduced to a few pixels if required but would obviously requires a lot more of the server's resources.

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
Is the availability of shapes, so unless you keep the 1 x 1s high or not selected until the end you will often be missing a filling piece so a pattern may not work.

If you pre build then it is just a matter of loading the random pattern selected from the lookup.
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
yes 1x1 is most flexible so will often be selected.

If you look at the code I have done, I stop the 1 x 1 until the end, and use it to plug.

Well true random will create potential for infinite loops, if you don't shrink and reduce the selection (remove randomness) it could loop forever.
 
Last edited:
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
The randomness is an interesting element.

If you roll a six sided dice a few thousand times, the chances are the average of those dice rolls with be close to 3.5 very unlikely it would be close to 1 or even to 2. If it was then we would consider the dice to be loaded and not random. So the mean is a way to prove - show randomness.

In this case the smaller pieces do tend to be used because of spatial constraint.

So it could be improved and less skewed by adding a weighting for a larger dimension, as you shrink to fit you will get the smaller shapes anyhow, that gives more of an illusion of randomness.
 
Last edited:
Upvote 0
..If you look at the code I have done, I stop the 1 x 1 until the end, and use it to plug...

As I said above thats not RANDOM. I could very easily modify my code to do this if required.

..Well true random will create potential for infinite loops, if you don't shrink and reduce the selection (remove randomness) it could loop forever.

I disagree again. The selection IS reduced for each image placement by removing those shapes that are impossible to fit. The actual shape used is chosen RANDOMLY from the shapes remaining. These shapes consist of ALL those that can fit so a fit is guaranteed removing the chance of an 'infinite loop'

Regards

Dotty
 
Upvote 0
...If you roll a six sided dice a few thousand times, the chances are the average of those dice rolls with be close to 3.5 very unlikely it would be close to 1 or even to 2...

The dice analogy doesn't apply in this case. When you roll a dice the previous throw has no influence on the following throw.

In this case the previously random chosen shapes can effect the outcome of the next shape (e.g it may only leave a small gap so only a small shape will be chosen - hence the relatively high frequency of the smallest shape)

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
You cannot have it both ways :)

shape_rows = random.randint( 2, img_rows )

That is still random with your idea of randomness.

You cannot predict what is the next number it could 2, 3 or 4 (or to whatever img_row is defined as). But it is constrained. So if you think that is not random, then it is because of the constraint.

And if you place a constraint of selection you are reducing randomness.

The plug is random as well, because they are created from random action, but again it is constrained to spatial so randomness is reduced.

I don't think you can get true randomness here, it leads to the potential of infinite loops.

It is the selection of images and what do with the empty that also leads to the potential of infinite loops, only some patterns can be made with a set of images where the elements where under a certain amount.

Oh this is interesting, if the set of images has enough images to fill the pattern with only their dimensions that problem would go away. So a 10 x 10 would need a 100 1x1s, 50 2x1s, 25 2x2s etc. Then there would always be an image available to fit a pattern.
 
Upvote 0
If the list of remaining shapes is empty then what?

Yeah if you shrink then you have moved out of random to a constraint.

That's impossible due to the 'ground rules' - all the images must be multiples of smallest image [the lowest common denominator] The smallest image will ALWAYS fit. In this case it is 50px but as I said it could be reduced at the expense of server resources.

It's still random because the only 'constraint' is the initial shapes available for selection.

Just because the lottery machine does not throw up a 99 ball doesn't mean it's not random. The 99 ball is impossible because it's not included in the first place.

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
The plugin doesn't actually happen with my algorithm, the shrinking gets it first so if only 1x1 is available it will shrink to it. But the plugin idea is valid as a speed up and a check, so I left it in :)

In the same vein as the 99 ball, you called this not random:

shape_rows = random.randint( 2, img_rows )

Game rules or rules remove randomness I thought that is what you were getting at, but if not, then the above is random.
 
Last edited:
Upvote 0
The plugin doesn't actually happen with my algorithm, the shrinking gets it first so if only 1x1 is available it will shrink to it. But the plugin idea is valid as a speed up and a check, so I left it in :)
...

No problem. Good chatting to you but I need to crash out. I will try and finish mine off when I get time.

Just one last thing though. The only rules I have been working to is this as posted by the OP:

"Images will be randomly and dynamically selected from a database
Image width and height will be in steps of 50px"


http://www.ebusinesswebsite.co.uk/csstest.php

Any other form of "weighting" will distort the true 'randomness' IMHO. I have however left plenty of provision for this should it be required.

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
Well true randomness is probably not even something to shoot for here.

We run into spatial constraint straight away, and true random does produce a chance of infinite.

So degrees of randomness, and here the algorithm I did will not create a grid of only 1x1s by design, it is not possible.

But what it will do is make the grid look more random, and select more different pieces, because the skew on the row and the shrinking. Smaller pieces can come up and only 1x1 has been blocked from first selection (only in shrink or plug), but once a piece is selected it is shrunk to fit, that redresses a bit the spatial constraint.

So it is all random, you couldn't predict what would happen, but it makes it look more designed as a random montage. People perceive randomness as a mix, if there is one of something or something dominates even though mathematically it is random, it doesn't look that way.

The infinite loop of worry is the images not being available, though if there are enough or can be repeated that goes, but again that would be quite time consuming making enough, and the repeat would remove from the random feel.

It is an interesting problem on many levels, the shrink is perhaps a little superfluous, but I like it because it gives a weighting to larger though it is inefficiently done, and not controlled enough. The patterns may look better with only a few large and majority mid, with the smaller ones dotted around, and that happens but the large could end up being too skewed if the range is increased.
 
Last edited:
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
The OP is long gone :)

I wouldn't worry about his rule set, long ago I worked out best to look for the final effect not a badly worded spec :)

It is a random montage of images, that fit a grid, that is what we are up to here.

Those images will not be randomly selected from a database, instead they will be randomly selected constrained to a range that will fit the available space.

And I suspect a repeated image is not desired as well, steps of 50 who cares could be steps of 1, it is the notion of a grid that is useful.
 
Last edited:
Upvote 0
...I wouldn't worry about his rule set, long ago I worked out best to look for the final effect not a badly worded spec :)
...

We seem to be at crossed purposes then. Somebody posted a problem and I posted the method I would use to solve it.

As I have said any 'weighting' may add artistic bias and 'look better' (although beauty is in the eye of the beholder!). Any 'weighted' solution will not truly be random however.

TBH I am not 100% sure what you are trying to achieve, Can you demonstrate it by turning your model into a working demo?

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
The code runs and gives output of a pattern in a matrix form. It works, just run it.

--

Weighting doesn't destroy randomness, it weights it. In this instance the spatial model is weighted to 1x1 which allows for that prediction that 1x1 will be more predominant, and it is in a lot of your patterns.

You cannot follow his spec to the letter, because if you just select random images each time and don't constrain there is a possibility that you won't select an image dimension that matches the available space, and it just keeps going round and round selecting outside of the available space.

It is a bit like the CSS part, if you add a containing div, you have used HTML and CSS to solve the problem, you stepped outside of the spec to make it work. So, if you slavishly follow that spec it won't work.

That's what I mean you cannot have it both ways, you are breaking the spec anyhow you are constraining randomness, you cannot just ignore that and highlight when I do it for the same reasons and say it is not RANDOM, sure it is not but in the same way neither is your method if it is to avoid an infiintie loop, so you constrain on a shrinking list i.e. the range is cropped.

The blocking of the 1x1 is trivial, the 2 can be replaced by a 1, so it is very deliberate it is not a side effect.

--

The gem of the stuff here is the random montage, and to create a system that works well in creating these random image montages, I suspect he wants one in PHP, well he can translate from either the Python code or if you supply your .NET code. But it has application on many sites.

My next move will be to create some images for a site, and then generate some patterns, discard the duplicates, and discard the patterns that won't work with the available images, I don't want repeats and I am not going to create thousands of images either, so then I will be left with some patterns that work. Then it will just be a matter of randomly selecting a pattern from the list at run time, I am assured each pattern will work and there will be very little load on the server as the pattern generation is done offline.
 
Upvote 0
I interpreted the spec as:

The images used will be predefined and have dimensions that fit a known pattern (i.e multiples of 50px)

The grid area will have predefined dimensions.

Each shape has an equal chance of being selected subject to the obvious constraints above.

The selections of the SUITABLE shapes will be totally RANDOM.

This is truly random. Just because you have PREDEFINED constraints does not mean the outcome is not random i.e my lottery analogy.

The purpose of the CSS is only to display the pattern achieved by the above and has no bearing on the pattern generated.

You seem to be looking at something a bit deeper which is interesting but not what I was trying to achieve.

Anyway I seem to have spent more time debating it than coding it so lets just agree to differ. When your web page is ready OP can decide which one is more suitable to his needs.

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
I am using this for my sites, as a general random montage.

I thought it would be fun to develop it up online, there is not a lot of difference in the two approaches from what I can make out from what you have said. Your code will be interesting to look at see the actual implementation.

It is the constraint, the shrinking, you can either shrink in range or shrink to fit. What I noticed was the weighting element and lowered the chance of the smaller blocks by design. The program displays the matrices at the end so I have seen lots of different patterns, it shows the build up as well.

I think when coding often people hold their idea in mind, I have got the patterns generating so I had time to look around at the different ones that do happen and how to smooth the effect.

There some alterations to do, make it a little more general.

I code in an agile development fashion with python, that's the beauty of python very quickly you can move ideas in and out, it is like pseudo code.
 
Last edited:
Upvote 0
Just one more thing!

It's worth repeating this:

Again it is down to the shapes used. The original [OPs] pattern was quite basic so I have used a similar form.

If a 50cm2 block appears once it stands to reason that it is likely to have others next to it since the other sizes will not fit in the gaps created.
...

IMO the key to a more 'artisitic' selection is to have a more suitable images shapes for 'building blocks' - The ones I have used are not ideal as there is to much of a difference between the smallest and the others - It's just a mock-up!

Regards

Dotty
 
Upvote 0

FireFleur

Free Member
Oct 29, 2008
1,880
440
The problem is a challenge on many levels. There is the spatial element to it, the rendering, the mathematics, aesthetics and of course the practicality of it.

It was your claim that it wasn't random that perplexed me, the spatial constraint forces it out of random to a reduced set of randomness.

One can either do that at the front or the end, doing it at the front which is what I think you do is more efficient, but I am batching this in part to keep server load down, and hone the patterns so efficiency is not central in my approach. At run time it will be super efficient no calculation necessary just a random number and a lookup. In real time you will want the algorithm to be efficient, so that is a difference in approach.

And you end up with something usable, OP well he is getting the design ideas that is worth more than PHP code :)
 
Upvote 0

MichaelG

Free Member
Sep 1, 2005
461
16
Berkshire
Dotty and Firefleur,

The OP has not gone away. I have been watching and I have been trying a different methods to get the effect I wanted.

Time was an issue - so this is what I ended up with as a quick solution to this problem.

# I created X pre-made grid patterns (a CSS template).
# I created X pre-defined folders to house different the sized images (e.g. 50x50, 100x150, etc)
# The system picks a grid pattern at random and then selects a random picture from a folder that contains the picture the fits the a grid space.
# Each picture is only be used once in a pattern.

I know its not perfect, but I had to do something quick to at least create the desired effect.

Dotty - I would love to see your demo/test with different images.

The system picks a grid pattern randomlyWhen a grid pattern is loaded/selected, the system picks random images from
 
Upvote 0
...
Dotty - I would love to see your demo/test with different images...

If you send me the images you want to use I will see what I can do.

Just remember BOTH the width and height must be exact multiples of 50px.

Based on you previous images, to save a bit of code, I also made the assumption that the width would not exceed the height. To make this a practicable application I will have to modify the code to accept images that are wider than they are high.

I might be a while until I get around to it though as I very busy at the moment and am easily distracted by this sort of thing (because it is much more fun that what I ought to be doing!). ;)

Regards

Dotty
 
Upvote 0

MichaelG

Free Member
Sep 1, 2005
461
16
Berkshire
I might be a while until I get around to it though as I very busy at the moment and am easily distracted by this sort of thing (because it is much more fun that what I ought to be doing!). ;)

I am sooooooooooo like you - easily distracted by the fun stuff ;)

I also made the assumption that the width would not exceed the height

This assumption is not right. The only constraint on image size is (exactly multiples of 50px)

If you send me the images

I will do this as soon as possible. I need to finish building a CRM for next week - so if you hear nothing from me for a while, I am not dead, just buried in work ;)

Thank you all for taking the time out to help with this not so easy problem. I am sure there is a maths formula somewhere to solve this problem - should have paid more attention in school ;)
 
Upvote 0
D

DotNetWebs

Just revisited this and sorted out the final row:

http://dotnetwebs.com/test/imagegrid/

Regards

Dotty

Google has just gone mad!

Just saw this result in third postion when searching for DotNetWebs;

Untiltled Page
150 x 200. 100 x 150. 50 x 50. 100 x 150. 50 x 50. 100 x 150. 50 x 50. 100 x 150 . 50 x 50. 100 x 150. 50 x 50. 200 x 250. 50 x 50. 100 x 150 ...

Hadn't a clue what it was all about when I saw it and only after clicking did I remember what it was.

This has ONLY ever been posted on this forum. Has no content other than the images yet it is now ranking above my Twitter Profile and various other high profile pages!.

Regards

Dotty
 
Upvote 0

Latest Articles