Java AWT/ImageIO: Bilinear and Bicubic scaling of a JPEG image result in completely black output -


nearest neighbor scaling works: entire picture stays intact when use type_nearest_neighbor.

even though scala code, used libraries standard java libraries.

functions:

def getbufferedimage(imagefile: java.io.file): bufferedimage = {     imageio.read(imagefile) }  def scaleimage(image: bufferedimage, minsize: double): bufferedimage = {     val before: bufferedimage = image     val w = before.getwidth()     val h = before.getheight()     val affit = new affinetransform()     var scale = 1.0     if(h < w) {       if(h > 0) {         scale = minsize / h       }     } else {       if(w > 0) {         scale = minsize / w       }     }     affit.scale(scale, scale)     val affitop = new affinetransformop(affit, affinetransformop.type_bicubic)     affitop.filter(before, null) }  def getimagejpegbytearray(image: bufferedimage): array[byte] = {     val baos = new java.io.bytearrayoutputstream()     val mcios = new memorycacheimageoutputstream(baos)     imageio.write(image, "jpeg", mcios)     mcios.close()     baos.tobytearray } 

calling code snippet:

val img = getbufferedimage(imagefile) val scaledimg = scaleimage(img, 512) val result = getimagejpegbytearray(scaledimg) // result written sqlite database 

result written sqlite database. if download database , save jpeg file, resulting jpeg is

  • as expected if use affinetransformop.type_nearest_neighbor
  • completely black if use affinetransformop.type_bilinear
  • completely black if use affinetransformop.type_bicubic

consequently, accuse affinetransformop of being buggy... how can solve problem?

file magic number of result ff d8 ff expected jpeg.

details

java version: java hotspot(tm) 64-bit server vm, java 1.7.0_71

operating system: apple, os x 10.9.5

test image: http://www.photos-public-domain.com/wp-content/uploads/2012/05/thundercloud-plum-blossoms.jpg

i able reproduce issue on java 1.7.0_71 on os x 10.10.4 (i rewrote code in java, can post full code if interested).

in case, problem not affinetransformop buggy in itself. in test program displayed image using minimal swing jframe , scaled image looked there. why people in comments did not understand problem.

part of issue bufferedimage returned affinetransformop when don't provide destination filter method (the second parameter, null in case), create 1 you. image type bufferedimage.type_int_argb. here relevant code affinetransformop.createcompatibledestimage() (lines 456-468, kept formatting, make easier spot):

colormodel cm = src.getcolormodel(); if (interpolationtype != type_nearest_neighbor &&     (cm instanceof indexcolormodel ||      cm.gettransparency() == transparency.opaque) {     image = new bufferedimage(w, h, bufferedimage.type_int_argb); } else {     image = new bufferedimage(cm,               src.getraster().createcompatiblewritableraster(w,h),               cm.isalphapremultiplied(), null); } 

notice special case type_nearest_neighbor, explains why you'll different behavior when using nearest neighbor algorithm. good, (as said, image displays fine in swing component).

the problem arises when try store image jpeg. during years, there's been lot of confusion , issues related imageio jpeg plugin , whether allow write images alpha channel (like type_int_argb image). allow that. but, argb jpegs misinterpreted cmyk jpegs (as 4 channels, , storing argb data in jpeg exotic) , displayed in funky colors. in case though, seems black...

so, there 2 possible solutions:

  • either write image in file format supports alpha channel, png or tiff (tiff requires plugin, might not best choice). this:

    imageio.write(image, "png", mcios); 
  • or, make sure bufferedimage in pixel format without alpha channel before storing jpeg. can after scaling, easiest (and fastest) provide affinetransformop explicit destination image, this:

    rectangle newsize = affitop.getbounds2d(before).getbounds(); return affitop.filter(before,        new bufferedimage(newsize.width,  newsize.height, bufferedimage.type_3byte_bgr)); 

here image, scaled program, using jpeg format , type_3byte_bgr:

scaled image

i'm sure can rewrite java code scala. :-)


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -