How to Stamp an Image Template with Context Specific Details.Page edited by Michael O'CleirighHow to Stamp an Image Template with Context Specific DetailsFor certain applications its useful to have an image template that can be stamped with contextual data when displayed to the end user. This example comes from an online travel survey is being conducted where there is a specific for which the trips will be collected. So to better inform the respondent we generate an image containing the window of time we are interested in and contextualize it with the specific date details that apply. Unable to render embedded object: File (example-surveyed-date.png) not found. The final image is constructed in several steps:
The generated image will be accessed through a hardcoded mount point. Wicket Setup:
Create custom IRequestTargetUrlCodingStrategy and bind it to the /surveyed-date.png ImageFirst we create the IRequestTargetUrlCodingStrategy that will respond to requests to /surveyed-date.png
public class SessionScopedSurveyTimeImageRequestTarget implements
IRequestTargetUrlCodingStrategy {
private static final Logger log = Logger
.getLogger(SessionScopedSurveyTimeImageRequestTarget.class);
// name of the image resource that we respond to
private static final String PATH = "surveyed-date.png";
// service that generates the final image for the current state.
private final TripTimeImageService tripTimeImageService;
// spring session bean proxy that contains the current survey sample
private final DataModelService dmService;
/**
* @param tripTimeImageService
*
*/
public SessionScopedSurveyTimeImageRequestTarget(TripTimeImageService tripTimeImageService, DataModelService dmService) {
this.tripTimeImageService = tripTimeImageService;
this.dmService = dmService;
}
@Override
public IRequestTarget decode(RequestParameters requestParameters) {
// default to yesterday
DateTime surveyedDate = new DateTime().minusDays(1);
if (dmService.isCreated()) {
// The surveyed date is set from the sample context.
surveyedDate = new DateTime ( dmService.getDataModel().getSample().getSurveyedDate());
}
Resource r;
try {
// this spring service generates the Image Resource stamped with 'surveyedDate' detail
r = tripTimeImageService.getImageResource(surveyedDate, true);
}
catch (IOException e) {
log.error("decode(): exception", e);
return null;
}
return new ResourceStreamRequestTarget (r.getResourceStream());
}
@Override
public CharSequence encode(IRequestTarget requestTarget) {
// intentionally does nothing
return null;
}
@Override
public String getMountPath() {
return PATH;
}
@Override
public boolean matches(IRequestTarget requestTarget) {
return false;
}
@Override
public boolean matches(String path, boolean caseSensitive) {
// handle the match detection, i.e. path.equals ("surveyed-date.png")
if (caseSensitive) {
if (PATH.equals(path))
return true;
else
return false;
}
else {
if (PATH.toLowerCase().equals(path.toLowerCase()))
return true;
else
return false;
}
}
}
Next we mount the strategy in Application.init(), as:
mount (new SessionScopedSurveyTimeImageRequestTarget(tripTimeService, dmService));
The tripTimeService.getImageResource(surveyedDate, true) method is what does the work of converting the date into a particular format and then writing the text onto an image template. How to create an image stamped with user specific context
public class TripTimeImageServiceImpl implements TripTimeImageService {
private static final Logger log = Logger
.getLogger(TripTimeImageServiceImpl.class);
// spring resource that points at the template image
private Resource baseTripTimeImageFile;
private DateTimeFormatter dayOfWeekFormatter;
private DateTimeFormatter dateFormatter;
// Font to use to write the string version of the date onto the image template
private static Font font = new Font(
Font.SANS_SERIF,
Font.BOLD,
14);
// cache containing the created image for each
private Map<String, BufferedDynamicImageResource> dateToImageMap = new LinkedHashMap<String, BufferedDynamicImageResource>();
private BufferedDynamicImageResource generateImage(DateTime surveyedDate,
SurveyTime st, boolean cacheable) throws IOException {
BufferedDynamicImageResource generatedImage = new BufferedDynamicImageResource(
"png");
String dow = dayOfWeekFormatter.print(surveyedDate);
String date = dateFormatter.print(surveyedDate);
DateTime nextDay = surveyedDate.plusDays(1);
String nextDow = dayOfWeekFormatter.print(nextDay);
String nextDate = dateFormatter.print(nextDay);
BufferedImage overlayImage = ImageIO.read(baseTripTimeImageFile.getFile());
int width = overlayImage.getWidth();
int height = overlayImage.getHeight();
Graphics2D overlayG2d = overlayImage.createGraphics();
overlayG2d.setFont(font);
overlayG2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
overlayG2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
overlayG2d.setPaint(Color.BLACK);
/*
* These offsets were calculated using a test case to repeatably place the details
* and with the Gimp to locate viable insertion points.
*/
// day of week
overlayG2d.drawString(dow, 32, 90);
// date
overlayG2d.drawString(date, 32, 107);
// next day of week
overlayG2d.drawString(nextDow, 332, 90);
// next date
overlayG2d.drawString(nextDate, 332, 107);
// next we write the progress bar onto its own image so thay we can layer them and have the bar at the back of the image stack.
BufferedImage target = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D targetG2d = target.createGraphics();
targetG2d.setFont(font);
targetG2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
targetG2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
targetG2d.setPaint(Color.white);
targetG2d.fillRect(0, 0, width, height);
targetG2d.setPaint(Color.RED);
// fill with the background color (white)
// targetG2d.fillRect(0, 0, width, height);
// draw the overlay (the printed surveyedDate detail) onto the target.
targetG2d.drawImage(overlayImage, 0, 0, null);
// do the final setup on the BufferedDynamicImageResource that will contain this image
// note that the generated image does not change the base image.
generatedImage.setImage(target);
generatedImage.setCacheable(cacheable);
generatedImage.setFormat("png");
log.info("generated image");
return generatedImage;
}
public void setBaseTripTimeImageFile(Resource baseTripTimeImageFile) {
this.baseTripTimeImageFile = baseTripTimeImageFile;
}
public TripTimeImageServiceImpl() {
// e.g Wednesday
dayOfWeekFormatter = DateTimeFormat.forPattern("EEEE");
// e.g. February 18, 2009
dateFormatter = DateTimeFormat.forPattern("MMMM dd, yyyy");
}
@Override
public org.apache.wicket.Resource getImageResource(DateTime surveyedDate, boolean cacheable)
throws IOException {
return getImageResource(surveyedDate, null, cacheable);
}
@Override
public org.apache.wicket.Resource getImageResource(DateTime surveyedDate,
SurveyTime previousDepartureTime, boolean cacheable) throws IOException {
BufferedDynamicImageResource cachedImage = null;
String cachedImageKey = TimeUtils.getInstance().getString(
surveyedDate);
cachedImage = this.dateToImageMap.get(cachedImageKey);
if (cachedImage == null) {
cachedImage = generateImage(surveyedDate, previousDepartureTime, cacheable);
this.dateToImageMap.put(cachedImageKey, cachedImage);
}
return cachedImage;
}
}
Linking to the dynamic image from your pages
<img src="" alt="Contextualized Image">
Unable to render embedded object: File (/home/mike/example-surveyed-date.png) not found.
Change Notification Preferences
View Online
|
View Change
|
Add Comment
|
- [CONF] Apache Wicket > How to Stamp an Image Template with C... confluence
- [CONF] Apache Wicket > How to Stamp an Image Template w... confluence
