RE: Image Table Helpppppppppppme

Add a
generated column
to the table, generating an
Embedded
component. Use a
StreamResource
to create an image resource from your byte array - e.g.
this sample
(click “View Source”) creates an Embedded showing an image from a byte array.

thanks:bashful:
thanks+10
thanks

Hi Henri Sara,

Please help me on this topic.

I am not able to figure out :open_mouth: how to convert the images received from mysql database to Vaadin Stream Source and display a final image on my table embedded component.

Please give me example code and reply soon.

thanks,

GlobalNeel

Hi,

Let us say you have your image in the byte array received from db. Then in order to add image to the table you just add a generated cell there.

  private final ColumnGenerator imageColumnGenerator = new ColumnGenerator()
  {
    public Component generateCell(final Table source, final Object itemId,
        final Object columnId)
    {
      StreamSource streamSource = new StreamSource()
      {
        public InputStream getStream()
        {
          final Item item = source.getItem(itemId);
          byte[] bas = (byte[]
) item.getItemProperty("preview").getValue();
          return (bas == null) ? null : new ByteArrayInputStream(bas);
        }
      };
      StreamResource resource = new DynamicImageResource(streamSource, getApplication());
      Embedded embedded = new Embedded("", resource);
      return embedded;
    }
  };

And then, somewhere in your logic:


table.addGeneratedColumn("preview", imageColumnGenerator);

Where DynamicImageResource is:

public class DynamicImageResource extends StreamResource
{
  public DynamicImageResource(StreamSource streamSource, Application application)
  {
    super(streamSource, null, application);
    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    String filename = "myfilename-" + df.format(new Date()) + ".png";
    setFilename(filename);
    setCacheTime(0l);
  }
}

PS: “preview” is a dummy property name that you have to substitute with your own.

Best Regards,
Alexander.

Hi Alexander,

Thanks a lot dear.

Regards,

GlobalNeel

To make this work on Vaadin 7
I had to tweak the code a bit

			public Object generateCell(Table source, Object itemId, Object columnId) {
				BeanItem<?> beanItem = (BeanItem<?>)source.getItem(itemId);
				FAFont  cayenneBase = (FAFont)beanItem.getBean();
		                final byte[]  imageBytes = cayenneBase.fontImageOfType("sample", 2);
				
				StreamSource streamSource = new StreamResource.StreamSource() {
					public InputStream getStream() {
						return (imageBytes == null) ? null : new ByteArrayInputStream(imageBytes);
					}
				};
				StreamResource imageResource = new StreamResource(streamSource, cayenneBase.gid() + ".png");
				Embedded embedded = new Embedded("", (Resource)imageResource);

				return embedded;
			}

Is there a way to do this with a Grid?

You should be able to use an ImageRenderer to display the image.

It does not work with image saved in database with byte array. I verified and ImageRenderer works only with file resource image. Do you have a workaround?

One possible workaround is to use the HTML renderer and create an image tag with a data url:

<img src="data:image/png;base64,..." alt="">

I coded a converter to pass the byte value to String and a renderer extending the HtmlRenderer. The renderer overrides the encode method which sets the html img tag. However, when my grid is displayed I do not see the images correctly. A small icon with a mountain appears indicating that the image is not loaded. Is it the correct way to do it?

public class ByteArrayToString implements Converter<String, byte[]> {

    private static final long serialVersionUID = 6893355715031071885L;

    public ByteArrayToString() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public byte[] convertToModel(String value, Class<? extends byte[]
> targetType, Locale locale)
            throws com.vaadin.data.util.converter.Converter.ConversionException {
        return Base64Utils.fromBase64(value);
    }

    @Override
    public String convertToPresentation(byte[] value, Class<? extends String> targetType, Locale locale)
            throws com.vaadin.data.util.converter.Converter.ConversionException {
        return Base64Utils.toBase64(value);
    }

    @Override
    public Class<byte[]> getModelType() {
        return byte[].class;
    }

    @Override
    public Class<String> getPresentationType() {
        return String.class;
    }

}


public class ByteArrayImageRenderer extends HtmlRenderer {
    
    private static final long serialVersionUID = 3813268410665010692L;

    @Override
    public JsonValue encode(String value) {
        String newValue = null;
        if (value != null) {
            newValue = "<img src=\"data:image/png;base64," + value + "\" />";
        }
        return super.encode(newValue);
    }

}

I used Base64 from apache codec and now the image is displayed.

However, the row height is not fitting the image. I tried the css trick from the grid part in the tutorial for the image renderer but it does nothing.

Please advise.