Cataster
Cataster

Reputation: 3521

Why is the image coming out blurry?

I have the following image that I'm trying to display under my navigation bar.

car

The image dimensions are 234 x 156 px

For some reason, the image is coming out blurry and the entire image cannot be seen. Is it because it's too small to begin with in terms of height/width? or some other factor?

Here is the code snippet that displays the image:

 <div class="flex w-full justify-center">
          <img
              src="../images/cars.png" alt= ""
              class= "h-48 w-full object-cover" />
    </div>

Upvotes: 0

Views: 499

Answers (2)

tao
tao

Reputation: 90048

h-48 w-full classes set the size of the image box (the rendering area). This box will have a height of 12rem (192px) and a width equal to its parent's.

In this box, .object-cover zooms the image in (or out, if original image size is larger than the box size), without changing pixel aspect ratio, to the minimum image size at which it covers the box entirely.

If the box's aspect ratio is equal to the image's, the image is not cropped. If it's not equal, the image is cropped on the axis on which it exceeds the box.

In your case, (guessing the width of the parent is fairly large - e.g: ~1000 - 1200px) the image is zoomed in until its width is equal to the box width and the excess is cropped (from top and bottom).

Which, most likely, makes the image pixelated, considering its enlarged 3-4 times (typically pixelation occurs above 2x original size).

Play with possible class combinations in the following demo:

const { createApp, reactive, toRefs } = Vue;

const app = createApp({
  setup() {
    const state = reactive({
      fits: ['contain', 'cover', 'fill', 'none', 'scale-down'],
      currentFit: 'cover',
      widths: ['full', '72', '64', '48'],
      currentWidth: 'full',
      labelClass: 'cursor-pointer hover:text-blue-500',
      optionLabels: ['Description', 'Crops image', 'Stretches image', 'Box background visible'],
      options: {
        contain: ['Image contained in box', false, false, true],
        cover: ['Image covers box', true, false, false],
        fill: ['Image stretched to box size', false, true, false],
        none: ['Image displayed without any scaling (original size), regardless of box sizes', true, false, true],
        'scale-down': ['Same as -none except large images are scaled down to fit box', false, false, true]
      }
    })
    return toRefs(state)
  }
})
app.mount('#app')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.45/vue.global.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<div id="app">
  <div class="flex w-full justify-center bg-gray-100">
    <img
      src="https://i.sstatic.net/8PUa3.png"
      alt=""
      class="h-48 border bg-fuchsia-400"
      :class="{[`object-${currentFit}`]: true, [`w-${currentWidth}`]: true }"
    />
  </div>
  <div class="container mx-auto">
    <div class="p-2 border-0 border-t border-zinc-200">
      <h2 class="font-bold text-xl">Object Fit:</h2>
      <label
        v-for="fit in fits"
        :key="fit"
        class="pr-2"
        :class="currentFit === fit ? '': labelClass"
      >
        <input type="radio" v-model="currentFit" :value="fit" />
        {{ `object-${fit}` }}
      </label>
    </div>
    <div class="p-2">
      <h2 class="font-bold text-xl">Width:</h2>
      <label
        v-for="width in widths"
        :key="width"
        class="pr-2"
        :class="currentWidth === width ? '': labelClass"
      >
        <input type="radio" v-model="currentWidth" :value="width" />
        {{ `w-${width}` }}
      </label>
    </div>
  </div>
  <div class="bg-gray-100 pb-8 pt-2 border-0 border-t border-zinc-200">
    <div class="container mx-auto grid grid-cols-3">
      <div class="font-bold pl-2 text-xl text-right pr-4" v-text="`.object-${currentFit}`"></div>
      <div class="col-span-2"></div>
      <template v-for="(label, index) in optionLabels" :key="index">
        <h3 class="italic px-4 text-right" v-text="`${label}:`"></h3>
        <code v-text="options[currentFit][index]" class="col-span-2"></code>
      </template>
    </div>
  </div>
</div>

  • I've added short descriptions for each object fit option
  • I've given the box a pink background and its parent a light grey background

Upvotes: 1

jjj
jjj

Reputation: 408

Assume you're on tailwind. Try a defined dimension

 <div class="flex w-full justify-center">
      <img
          src="../images/cars.png" alt= ""
          class= "h-48 w-72 object-cover" />
</div>

or object-contain


     <div class="flex w-full justify-center">
          <img
              src="../images/cars.png" alt= ""
              class= "h-48 w-full object-contain" />
    </div>

to narrow down the cause to css sizing instead of other issues

Upvotes: 1

Related Questions