public function renderImage(MediaInterface $image, array $columns, array $attr = [])
    {
        if (!$image->getType() === MediaTypes::IMAGE) {
            throw new InvalidArgumentException("Expected 'image' media type.");
        }

        $map = [];
        $col = 12;
        foreach (array_reverse(Bootstrap3Adapter::getDevices(), true) as $d => $config) {
            $col = isset($columns[$d]) ? $columns[$d] : $col;
            $count = 12 / $col;
            $map[sprintf('col_%s_%d', $d, $col)] = [
                'max'   => $config['max'],
                'width' => intval(($config['width'] - ($count - 1) * 30) / $count),
            ];
        }

        $url = null;
        $srcSet = [];
        $sizes = [];
        foreach ($map as $filter => $config) {
            $url = $this->manager->getBrowserPath($image->getPath(), $filter);
            $srcSet[] = $url . ' ' . $config['width'] . 'w';
            $sizes[] = trim(
                ($config['max'] ? '(max-width:' . $config['max'] . 'px)' : '') . ' ' . $config['width'] . 'px'
            );
        }

        if (!isset($attr['alt'])) {
            $attr['alt'] = $image->getTitle();
        }

        $attr['src'] = $url;
        $attr['srcset'] = implode(', ', $srcSet);
        $attr['sizes'] = implode(', ', $sizes);

        $attributes = implode(' ', array_map(function($key, $value) {
            return sprintf('%s="%s"', $key, $value);
        }, array_keys($attr), $attr));


        return "<img $attributes>";
    }