jgarber623 / spaceholder.cc

A space-themed image placeholder service.
https://spaceholder.cc
MIT License
32 stars 3 forks source link

Add a way to consistently get the same image #5

Open bryanburgers opened 8 years ago

bryanburgers commented 8 years ago

It would be nice if there was a way to make a request using a stable URL and always get the same image back for that request.

One simple option

I have seen some placeholder services that will always return the same image for a given size. For example, service/300x300, no matter how many times you request it or where from, it will always return the same image instead of a random image.

This option isn't great though, because frequently mockup pages will have multiple img tags of the same size, and would want different photos to populate them.

User-provided value option

The first thing I thought of would be to add another value, e.g. service/300x300/1, service/300x300/2, service/300x300/3315fa35180cz3. This number wouldn't really be an identifier. Instead, the service could take the extra value and make a hash of it, and somehow have a stable mapping of hash to image.

service/300x300 would still return a random image. But if a user wants to use a stable identifier and get a consistent image, they can provide any value after the size. (I don't know how difficult this would be with the API, though.)

The advantages is that a mockup could still have different images for different tags

<figure>
  <img src="http://spaceholder.cc/300x300/first-thing">
  <figcaption>First Thing</figcaption>
</figure>
<figure>
  <img src="http://spaceholder.cc/300x300/second-thing">
  <figcaption>Second Thing</figcaption>
</figure>
<figure>
  <img src="http://spaceholder.cc/300x300/third-thing">
  <figcaption>Third Thing</figcaption>
</figure>

Other options

I haven't thought this far, but there might be better ideas out there.

bryanburgers commented 8 years ago

Simplistically, if you had 16 images instead of 11, you could do (pseudocode, I'm not real up on Ruby)

class Image
  def initialize(dimensions)
    @image = MiniMagick::Image.open(Dir.glob('./app/assets/images/photos/*.jpg').sample)
    @dimensions = dimensions
  end

  def initialize(dimensions, stableid)
    # get a hash that, given dimensions and stableid, is always the same.
    sha = sha1(dimensions.width + dimensions.height + stableid)

    # get the first character of the hash
    indexstring = substring(sha, 0, 1)

    # turn that first character into a number between 0 and 15
    index = hexToInt(indexstring)

    # this assumes you have exactly 16 images in the photos directory, though. Should be safe and check.
    @image = MiniMagick::Image.open(Dir.glob('./app/assets/images/photos/*.jpg')[index]) 
    @dimensions = dimensions
  end

I'm sure with more thinking, there would be a good way to turn a hash into an index for any size array.