There are a number of challenges to produce such a pattern - in particular manipulating the 'seed' pattern to rotate and scale it along with being able to clone it and produce many overlapping copies.
Here's the final result :
Starting with a 'heart' node group we can generate a single instance of the pattern :
The heart will be centred around (0,0) so using Object coordinates will position it at the origin of the object. This is important since it is the origin that will be used for any rotation and scaling.
Rotation can be achieve with the following node group :
This applies the rotation using SIN and COS functions as :
$X = x*cos(angle) - y*sin(angle)$
$Y = x*sin(angle) + y*cos(angle)$
Note that the input Rotation is multiplied by $2*pi$ so that 0.0 to 1.0 relates to a full rotation.
Similarly, scaling can be produced by a Scale node group :
In order to get multiple hearts we need to arrange the input coordinates so that we can generate multiple 'origins' - with each 'heart' centred on an 'origin' where the coordinates are (0,0). We can achieve this using the Modulo function. The Modulo takes one input value and divides it by the other, outputting the remainder. In this way as the input increases the output will also increase but once it reaches the divisor value will jump back down to zero and begin again. By using the Modulo function on both the X and the Y coordinates we can break the texture space into a number of cells - similar to that described here https://blender.stackexchange.com/a/26703/29586.
Note how the Modulo result produces repeating coordinates - useful for our multiple origins. By subtracting the Modulo from the orignal vector we can create an output that is constant over each cell - we can use this to generate a random value for rotation/scale per cell.
Using these manipulated coordinates we can create multiple hearts - one per cell :
Using Noise textures we can generate a displacement, rotation, and scale for each instance of the heart.
Note, however, that each heart is bound by the walls of its cell - try and move them outside this region and it will be clipped. This means that the generated hearts can never actually overlap.
One way to address this is for each cell to also render the hearts from its immediate neighbours. This will allow elements to overlap to the extent of one whole cell. Keeping the displacement low enough to ensure that no heart extends beyond its neighbours' boundaries will avoid clipping at those further boundaries.
To demonstrate, see the following image :
In the above image the cell edges have been shown and the hearts coloured based on which 'cell' it is acually originating from - with white representing it being within the boundary of its own cell, blue shows where it is the heart from the cell to the 'west', red the heart from the 'east', yellow and green from the south and north respectively, cyan, brown, orance, light-blue for the corners.
These 'neighbour' hearts are generated by an extra set of 'heart' node groups, offset based on a set of additional vectors set to '(-1,-1)', '(-1,0)', '(-1,1)', '(0,-1)', '(0,1)', '(1,-1)', '(1,0)', '(1,1)'.
The outputs from each of these groups are combined (using simple Maximum maths nodes) to produce the final output.
To extend this to images, all that is required is to replace the 'heart' node with the image (adjusted to set the origin to the centre) and change the method of combining the images to take account of the color channels.
The above may seem overly complicated but it does convey a significant advantage - the rendering of each 'cell' can take account of the position, location and scale of all surrounding cells. This allows for some interesting effects such as custom Voronoi, blending between objects, controlling how they overlap, etc. - either those 'bigger' ones always on top, for example, or scales (fish scales, dragon scales, etc.) could be randomly displaced and overlapped, but those further 'up' the texture always overlaying those 'below' - but that's outside the scope of this answer.
Blend file included