Resizing .tif image with imgscalr - resize

I am trying to resize a .tif image and then display it on the browser by converting it to a base64 string. Since ImageIo doesn't support TIF images by default, i have added imageio_alpha-1.1.jar(got it here - http://www.findjar.com/jar/geoserver/jai/jars/jai_imageio-1.1-alpha.jar.html). Now ImageIO is able to register the plugin, which i checked by doing this
String[] writerNames = ImageIO.getWriterFormatNames();
writerNames has TIF in it, this means ImageIO has registered the plugin.
I am resizing the image like this
Map resizeImage(BufferedImage imageData, int width, int height, String imageFormat){
BufferedImage thumbnail = Scalr.resize(imageData, Scalr.Method.SPEED, Scalr.Mode.FIT_EXACT ,
width, height, Scalr.OP_ANTIALIAS);
String[] writerNames = ImageIO.getWriterFormatNames();
ByteArrayOutputStream baos = new ByteArrayOutputStream()
ImageIO.write(thumbnail, imageFormat, baos)
baos.flush()
byte[] imageBytes = baos.toByteArray()
baos.close()
return [imageBytes:imageBytes, imageFormat:imageFormat]
}
String encodeImageToBase64(byte[] imageData){
return Base64.encodeBase64String(imageData)
}
BufferedImage getBufferedImage(byte[] imageData){
ByteArrayInputStream bais = new ByteArrayInputStream(imageData)
BufferedImage bImageFromConvert = ImageIO.read(bais)
bais.close()
return bImageFromConvert
}
String resizeToDimensions(byte[] imageData, String imageFormat, int width, int height){
def bimg = getBufferedImage(imageData)
Map resizedImageData = resizeImage(bimg, width, height, imageFormat)
return encodeImageToBase64(resizedImageData.imageBytes)
}
now i am displaying the image like this
< img src = "data:image/tif;base64,TU0AKgAAAAgADAEAAAMAAA...." /> with this i get failed to load url message(on hovering)
as far as i know the base64 string usually starts with /9j/(may be i am wrong). when i am appending /9j/. I get an error - "image corrupt or truncated". I am not able to figure out the problem here, please help.

At first glance your use of the Data URI format looks correct -- try and narrow down exactly where the failure is.
I would recommend:
In your method where you return the string to the front end, I would recommend printing the entire thing out to the console to get the raw data in Data URI format.
Take the Data URI string, create a sample HTML file with the hard-coded value in it, try and load it... does the image display? If so, great, then your problem is with how you are streaming that back to the front end or how you are trying to load it. (Likely a JavaScript/DOM issue)
If that doesn't work, try and chop the Base64 section out of the example and save it into an example TXT file. In your Java code, load it, decode it and try and create an image out of it and write it back out to a TIFF -- if that didn't work, then there is something wrong with your Base64 handling and the encoding is invalid most likely.
Getting that far should answer most of the questions.
Actually now that I think about it, try and use ImageIO to read the image into a BufferedImage, then process it with imgscalr, then immediately call ImageIO.write and try and write it out to a new TIF someplace else and make sure the ImageIO decoding/encoding process is working correctly.
Hope that helps!

Related

How can I draw a text into a buffered image with different font affects in Java 2d?

I am trying to convert Multi-line Text to image but couldn't found a way to draw it with different Font format's is there any way to do it.Thanks in Advance.
What you could do is simply loading an image, and then setting it as the default graphics context, and then drawing text with a Graphics2D object using different fonts. Here's how you could do this :
BufferedImage image = ImageIO.load(new File("test.png"));
Graphics2D g2d = image.createGraphics();
g2d.setFont(new Font("TimesRoman", Font.PLAIN, fontSize));
g2d.drawString("test", posx, posy, etc.)
If you want simply to draw to a blank image and then save it, just create a BufferedImage using the default constructor. Then, to save the image :
File output = new File("test.png");
ImageIO.write(image, "png", output);
If you want to know more about this, here's a link to Oracle's Java2D tutorials : https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html
(from where these examples are).

PNG file is corrupt when reading back from SQL

I have a database program that stores images to the SQL DB and reads them back to be displayed in a WPF application. if i use Jpeg images it works fine, but if i use PNG images, which i wanted to use to try and keep the transparency ( which disappears anyway when stored ) most of the images come back corrupt.
this is the image that has been selected
i then save it to the db, and add the image the listview
then if i close the application and reload it, it pulls the image back from the db, you can see that it is corrupt in the listview
and then when i select it, the image control also shows the corrupted image
i am storing the image in code using a BitmapImage object, and use this to set the image.source, and also convert this to a byte[] for storing into the image field in the database.
i convert the bitmapimage to a Byte[] with the following line
command.Parameters.AddWithValue("#Image", ImageToByteArray(productImage.ProductImage));
and these are the functions to convert to and from a bitmapimage
private static BitmapImage BuildImage(byte[] image)
{
var bitmap = new BitmapImage();
bitmap.BeginInit();
MemoryStream mem = new MemoryStream(image);
bitmap.StreamSource = mem;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
//bitmap.Freeze();
return bitmap;
}
private static byte[] ImageToByteArray(BitmapImage image)
{
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
works fine with Jpegs, but then i have the white background to the images.
any help would be much appreciated.
"JpegBitmapEncoder" is a large clue. Surely you'd want "PNGBitmapEncoder"...?
As personal preference I would change your SQL data column to varbinary(MAX) and use stream and BinaryReader objects to upload the file.
However I think your issue is you are not using PngBitmapEncoder for the PNG you are using the JpegBitmapEncoder irrespective of filetype.
Hope this helps.

ImageBuilder.Current.DecodeStream() doesn't resize

I'm passing a memory stream to the ImageBuilder.Current.DecodeStream() method, with some resize settings, but it's not resizing the resulting bitmap.
var bitmapData = Convert.FromBase64String(base64Image.FixBase64ForImage());
var streamBitmap = new MemoryStream(bitmapData);
var bitImage = ImageBuilder.Current.DecodeStream(streamBitmap, settings, "");
FixBase64ForImage() is just an extension method I wrote to remove the data:image/jpg;;base64, from the submitted base64 encoded photo.
I pass a 640x640 square photo to the ImageBuilder.Current.DecodeStream() method, and pass it settings that looks like this
var settings = new ResizeSettings(string.Format("maxwidth={0}&maxheight={1}&format={2}&crop={3}&quality={4}", maxwidth, maxheight,format, crop, quality));
No matter what max width/height I pass it, it always returns the full 640x640 photo (and seems like there is no quality compression as well).
This leads me to believe the resize settings are simply ignored. Is there another way to accomplish the same thing, or am I doing this wrong?
ImageBuilder.Current.DecodeStream does not do any image processing; it is only for decoding an image stream into an image bitmap. It is called by .LoadImage(), among others.
Use the .Build() overloads to perform image processing.

WinJS / WinRT: detect corrupt image file

I'm building a Win8/WinJS app that loads pictures from the local pictures library. Everything is generally working fine for loading valid images and displaying them in a list view.
Now I need to detect corrupt images and disable parts of the app for those images.
For example, open a text file and enter some text in it. Save the file as .jpg, which is obviously not going to be a valid jpg image. My app still loads the file because of the .jpg name, but now I need to disable certain parts of the app because the image is corrupt.
Is there a way I can check to see if a given image that I've loaded is a valid image file? To check if it's corrupt or not?
I'm using standard WinRT / WinJS objects like StorageFile, Windows.Storage.Search related objects, etc, to load up my image list based on searches for file types.
I don't need to filter out corrupt images from the search results. I just need to be able to tell if an image is corrupt after someone selects it in a ListView.
One possible solution would be to check the image's width and height properties to determine whether it is valid or not.
Yeah, the contentType property will return whatever the file extension is. The best way I can find it to look at the image properties:
file.properties.getImagePropertiesAsync()
.done(function(imageProps) {
if(imageProps.width === 0 && imageProps.height === 0) {
// I'm probably? likely? invalid.
});
where SelectImagePlaceholder is an Image Control.. =)
StorageFile file;
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
try
{
// Set the image source to the selected bitmap
BitmapImage bitmapImage = new BitmapImage();
await bitmapImage.SetSourceAsync(fileStream);
SelectImagePlaceholder.Source = bitmapImage;
//SelectImagePlaceholder.HorizontalAlignment = HorizontalAlignment.Center;
//SelectImagePlaceholder.Stretch = Stretch.None;
this.SelectImagePlaceholder.DataContext = file;
_curMedia = file;
}
catch (Exception ex)
{
//code Handle the corrupted or invalid image
}
}

Page by page conversion of PDF into TIFF with proper compression

Problem
There are PDF documents with different type of objects inside. There are simple texts. There can be scanned images that are B&W, and also other images, that are true color. The resolution can be quite high for both (~1789X2711).
I need to convert the PDF into a set of single page TIFF files. There are quite good tools for that. For example Irfanview, ImageMagick. The problem is that I have to define a single compression type for all the pages.
Using JPG for all pages would result in loosing details for B&W images and they would be huge compared to lossless fax compression.
Using lossless fax for all would wanish colors and details of true color images.
Idea
It would be nice to examine the PDF page by page. I could check the content of the page. What kind of images are there inside, and which compression is recommanded for the particular page. I think this can be done with IText, but I don't know exactly, how it should be done. A second thing is that I want to do this analysis without fully reading the PDF file. Is it possible?
Maybe the fastest solution would be to create a list of pages for each compression type with IText analysis, and then to call Irfanview to process the choosen pages with the proper compression.
Any ideas and recommendations are welcome.
UPDATE:
I have now an answer. It does not cover all requirements, and its not freeware. Any opensource ideas? Maybe Java based solutions?
This can be done with DotImage DotPdf from Atalasoft (cue the obligatory "I work there and work on these products"). Here is how I would do this task in C#:
PdfImageSource source = new PdfImageSource(pdfStream);
while (source.HasMoreImages()) {
AtalaImage image = source.AcquireNext();
string fileName = GetNextTiffName();
using (FileStream outStm = new FileStream(fileName, FileMode.Create)) {
TiffEncoder encoder = new TiffEncoder();
encoder.Compression = SelectCompression(image.PixelFormat);
image.Save(outStm, encoder, null);
}
source.Release(image);
}
private TiffCompression SelectCompression(PixelFormat pf)
{
switch (pf) {
// 1 bit? use CCITT G4
case PixelFormat.Pixel1bbIndexed: return TiffCompression.Group4FaxEncoding;
// 24 bit? use JPEG
case PixelFormat.Pixel24bppBgr: return TiffCompression.JpegCompression;
// all else, Lzw
default: return TiffCompression.Lzw;
}
}
You can make SelectCompression do pretty much whatever you want. If you select an invalid compression for that pixel format, the encoder will use an appropriate lossless one in its place (for example, if you select CCITT for 24bit color, the encoder will instead use Lzw).
Our PDF decoder knows when a PDF page is just gray and returns a gray image. It does NOT do anything to get you to 1 bit (this is so antialiased text looks good), however you could threshold the gray image and look at the overall differences between it and the gray image to determine if it could go to 1 bit).
Here's how you could do a set of pages:
public void ExtractNPages(Stream pdfStream, params int[] pageIndexes)
{
PdfImageSource source = new PdfImageSource(pdfStream);
for (int i in pageIndexes) {
AtalaImage image = source[i]; // implied Acquire
string fileName = GetNextTiffName();
using (FileStream outStm = new FileStream(fileName, FileMode.Create)) {
TiffEncoder = new TiffEncoder();
encoder.Compression = SelectCompression(image.PixelFormat);
image.Save(outStm, encoder, null);
}
source.Release(image);
}
}
so now you can just do ExtractNPages(stm, 0, 2, 4, 6);