diff --git a/python/vyos/utils/convert.py b/python/vyos/utils/convert.py
index 9a8a1ff7d..c02f0071e 100644
--- a/python/vyos/utils/convert.py
+++ b/python/vyos/utils/convert.py
@@ -1,197 +1,200 @@
 # Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # License as published by the Free Software Foundation; either
 # version 2.1 of the License, or (at your option) any later version.
 #
 # This library is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # Lesser General Public License for more details.
 #
 # You should have received a copy of the GNU Lesser General Public
 # License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
 def seconds_to_human(s, separator=""):
     """ Converts number of seconds passed to a human-readable
     interval such as 1w4d18h35m59s
     """
     s = int(s)
 
     week = 60 * 60 * 24 * 7
     day = 60 * 60 * 24
     hour = 60 * 60
 
     remainder = 0
     result = ""
 
     weeks = s // week
     if weeks > 0:
         result = "{0}w".format(weeks)
         s = s % week
 
     days = s // day
     if days > 0:
         result = "{0}{1}{2}d".format(result, separator, days)
         s = s % day
 
     hours = s // hour
     if hours > 0:
         result = "{0}{1}{2}h".format(result, separator, hours)
         s = s % hour
 
     minutes = s // 60
     if minutes > 0:
         result = "{0}{1}{2}m".format(result, separator, minutes)
         s = s % 60
 
     seconds = s
     if seconds > 0:
         result = "{0}{1}{2}s".format(result, separator, seconds)
 
     return result
 
-def bytes_to_human(bytes, initial_exponent=0, precision=2):
+def bytes_to_human(bytes, initial_exponent=0, precision=2,
+                   int_below_exponent=0):
     """ Converts a value in bytes to a human-readable size string like 640 KB
 
     The initial_exponent parameter is the exponent of 2,
     e.g. 10 (1024) for kilobytes, 20 (1024 * 1024) for megabytes.
     """
 
     if bytes == 0:
         return "0 B"
 
     from math import log2
 
     bytes = bytes * (2**initial_exponent)
 
     # log2 is a float, while range checking requires an int
     exponent = int(log2(bytes))
+    if exponent < int_below_exponent:
+        precision = 0
 
     if exponent < 10:
         value = bytes
         suffix = "B"
     elif exponent in range(10, 20):
         value = bytes / 1024
         suffix = "KB"
     elif exponent in range(20, 30):
         value = bytes / 1024**2
         suffix = "MB"
     elif exponent in range(30, 40):
         value = bytes / 1024**3
         suffix = "GB"
     else:
         value = bytes / 1024**4
         suffix = "TB"
     # Add a new case when the first machine with petabyte RAM
     # hits the market.
 
     size_string = "{0:.{1}f} {2}".format(value, precision, suffix)
     return size_string
 
 def human_to_bytes(value):
     """ Converts a data amount with a unit suffix to bytes, like 2K to 2048 """
 
     from re import match as re_match
 
     res = re_match(r'^\s*(\d+(?:\.\d+)?)\s*([a-zA-Z]+)\s*$', value)
 
     if not res:
         raise ValueError(f"'{value}' is not a valid data amount")
     else:
         amount = float(res.group(1))
         unit = res.group(2).lower()
 
         if unit == 'b':
             res = amount
         elif (unit == 'k') or (unit == 'kb'):
             res = amount * 1024
         elif (unit == 'm') or (unit == 'mb'):
             res = amount * 1024**2
         elif (unit == 'g') or (unit == 'gb'):
             res = amount * 1024**3
         elif (unit == 't') or (unit == 'tb'):
             res = amount * 1024**4
         else:
             raise ValueError(f"Unsupported data unit '{unit}'")
 
     # There cannot be fractional bytes, so we convert them to integer.
     # However, truncating causes problems with conversion back to human unit,
     # so we round instead -- that seems to work well enough.
     return round(res)
 
 def mac_to_eui64(mac, prefix=None):
     """
     Convert a MAC address to a EUI64 address or, with prefix provided, a full
     IPv6 address.
     Thankfully copied from https://gist.github.com/wido/f5e32576bb57b5cc6f934e177a37a0d3
     """
     import re
     from ipaddress import ip_network
     # http://tools.ietf.org/html/rfc4291#section-2.5.1
     eui64 = re.sub(r'[.:-]', '', mac).lower()
     eui64 = eui64[0:6] + 'fffe' + eui64[6:]
     eui64 = hex(int(eui64[0:2], 16) ^ 2)[2:].zfill(2) + eui64[2:]
 
     if prefix is None:
         return ':'.join(re.findall(r'.{4}', eui64))
     else:
         try:
             net = ip_network(prefix, strict=False)
             euil = int('0x{0}'.format(eui64), 16)
             return str(net[euil])
         except:  # pylint: disable=bare-except
             return
 
 
 def convert_data(data) -> dict | list | tuple | str | int | float | bool | None:
     """Filter and convert multiple types of data to types usable in CLI/API
 
     WARNING: Must not be used for anything except formatting output for API or CLI
 
     On the output allowed everything supported in JSON.
 
     Args:
         data (Any): input data
 
     Returns:
         dict | list | tuple | str | int | float | bool | None: converted data
     """
     from base64 import b64encode
 
     # return original data for types which do not require conversion
     if isinstance(data, str | int | float | bool | None):
         return data
 
     if isinstance(data, list):
         list_tmp = []
         for item in data:
             list_tmp.append(convert_data(item))
         return list_tmp
 
     if isinstance(data, tuple):
         list_tmp = list(data)
         tuple_tmp = tuple(convert_data(list_tmp))
         return tuple_tmp
 
     if isinstance(data, bytes | bytearray):
         try:
             return data.decode()
         except UnicodeDecodeError:
             return b64encode(data).decode()
 
     if isinstance(data, set | frozenset):
         list_tmp = convert_data(list(data))
         return list_tmp
 
     if isinstance(data, dict):
         dict_tmp = {}
         for key, value in data.items():
             dict_tmp[key] = convert_data(value)
         return dict_tmp
 
     # do not return anything for other types
     # which cannot be converted to JSON
     # for example: complex | range | memoryview
     return
diff --git a/src/op_mode/image_info.py b/src/op_mode/image_info.py
index ae0677196..14dca7476 100755
--- a/src/op_mode/image_info.py
+++ b/src/op_mode/image_info.py
@@ -1,108 +1,112 @@
 #!/usr/bin/env python3
 #
 # Copyright 2022 VyOS maintainers and contributors <maintainers@vyos.io>
 #
 # This file is part of VyOS.
 #
 # VyOS is free software: you can redistribute it and/or modify it under the
 # terms of the GNU General Public License as published by the Free Software
 # Foundation, either version 3 of the License, or (at your option) any later
 # version.
 #
 # VyOS is distributed in the hope that it will be useful, but WITHOUT ANY
 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 # details.
 #
 # You should have received a copy of the GNU General Public License along with
 # VyOS. If not, see <https://www.gnu.org/licenses/>.
 
 import sys
 from typing import List, Union
 
-from hurry.filesize import size
 from tabulate import tabulate
 
 from vyos import opmode
 from vyos.system import disk, grub, image
+from vyos.utils.convert import bytes_to_human
 
 
 def _format_show_images_summary(images_summary: image.BootDetails) -> str:
     headers: list[str] = ['Name', 'Default boot', 'Running']
     table_data: list[list[str]] = list()
     for image_item in images_summary.get('images_available', []):
         name: str = image_item
         if images_summary.get('image_default') == name:
             default: str = 'Yes'
         else:
             default: str = ''
 
         if images_summary.get('image_running') == name:
             running: str = 'Yes'
         else:
             running: str = ''
 
         table_data.append([name, default, running])
     tabulated: str = tabulate(table_data, headers)
 
     return tabulated
 
 
 def _format_show_images_details(
         images_details: list[image.ImageDetails]) -> str:
     headers: list[str] = [
         'Name', 'Version', 'Storage Read-Only', 'Storage Read-Write',
         'Storage Total'
     ]
     table_data: list[list[Union[str, int]]] = list()
     for image_item in images_details:
         name: str = image_item.get('name')
         version: str = image_item.get('version')
-        disk_ro: int = size(image_item.get('disk_ro'))
-        disk_rw: int = size(image_item.get('disk_rw'))
-        disk_total: int = size(image_item.get('disk_total'))
+        disk_ro: str = bytes_to_human(image_item.get('disk_ro'),
+                                      precision=1, int_below_exponent=30)
+        disk_rw: str = bytes_to_human(image_item.get('disk_rw'),
+                                      precision=1, int_below_exponent=30)
+        disk_total: str = bytes_to_human(image_item.get('disk_total'),
+                                         precision=1, int_below_exponent=30)
         table_data.append([name, version, disk_ro, disk_rw, disk_total])
-    tabulated: str = tabulate(table_data, headers)
+    tabulated: str = tabulate(table_data, headers,
+                              colalign=('left', 'left', 'right', 'right', 'right'))
 
     return tabulated
 
 
 def show_images_summary(raw: bool) -> Union[image.BootDetails, str]:
     images_available: list[str] = grub.version_list()
     root_dir: str = disk.find_persistence()
     boot_vars: dict = grub.vars_read(f'{root_dir}/{image.CFG_VYOS_VARS}')
 
     images_summary: image.BootDetails = dict()
 
     images_summary['image_default'] = image.get_default_image()
     images_summary['image_running'] = image.get_running_image()
     images_summary['images_available'] = images_available
     images_summary['console_type'] = boot_vars.get('console_type')
     images_summary['console_num'] = boot_vars.get('console_num')
 
     if raw:
         return images_summary
     else:
         return _format_show_images_summary(images_summary)
 
 
 def show_images_details(raw: bool) -> Union[list[image.ImageDetails], str]:
     images: list[str] = grub.version_list()
     images_details: list[image.ImageDetails] = list()
     for image_name in images:
         images_details.append(image.get_details(image_name))
 
     if raw:
         return images_details
     else:
         return _format_show_images_details(images_details)
 
 
 if __name__ == '__main__':
     try:
         res = opmode.run(sys.modules[__name__])
         if res:
             print(res)
     except (ValueError, opmode.Error) as e:
         print(e)
         sys.exit(1)