Home > Back-end >  Why is the image coming out blurry?
Why is the image coming out blurry?

Time:11-28

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 >
          <img
              src="../images/cars.png" alt= ""
              class= "h-48 w-full object-cover" />
    </div>

CodePudding user response:

Assume you're on tailwind. Try a defined dimension

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

or object-contain


     <div >
          <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

CodePudding user response:

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 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 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 >
    <img
      src="https://i.stack.imgur.com/8PUa3.png"
      alt=""
      
      :
    />
  </div>
  <div >
    <div >
      <h2 >Object Fit:</h2>
      <label
        v-for="fit in fits"
        :key="fit"
        
        :
      >
        <input type="radio" v-model="currentFit" :value="fit" />
        {{ `object-${fit}` }}
      </label>
    </div>
    <div >
      <h2 >Width:</h2>
      <label
        v-for="width in widths"
        :key="width"
        
        :
      >
        <input type="radio" v-model="currentWidth" :value="width" />
        {{ `w-${width}` }}
      </label>
    </div>
  </div>
  <div >
    <div >
      <div  v-text="`.object-${currentFit}`"></div>
      <div ></div>
      <template v-for="(label, index) in optionLabels" :key="index">
        <h3  v-text="`${label}:`"></h3>
        <code v-text="options[currentFit][index]" ></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
  • Related