Invalid SOS parameters for sequential JPEG
You can ignore the error with
ini_set ('gd.jpeg_ignore_warning', 1);
(this is the default since PHP 7.1, but not in older versions)
See http://php.net/manual/en/image.configuration.php
Using jpegtran to rotate progressive jpegs: invalid SOS parameter for sequential jpeg
I suspect that the source of the problem is that the spectral selection fields in the SOS marker are set to zero. These fields are meaningless in sequential JPEG but the standard says the values should be set to 0 and 63. Some JPEG references one sees on the internet say these values are ignored. Probably some encoders do not set them.
You might want to run a JPEG dumping program on your images to see if your spectral selection values are set to zero and 63. If they are not, you can write a relatively simple filter program that copies the JPEG stream while changing the spectral selection values.
I expect that the JPEGTRAN source code is online. If I am correct that it is making this needless check, you could build your own version with this commented out.
imagecreatefromjpeg() - Invalid SOS parameters for sequential JPEG
Set PHP to ignore jpeg warnings
ini_set ('gd.jpeg_ignore_warning', 1);
on the line just before invoking imagecreatefromjpeg()
Cannot load JPEG with java created by Samsung phone
Your question is awesome, really made me think and search for a couple of hours)
Here is a bit hacky solution (without 3rd party libs) that I ended up with:
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.PixelGrabber;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
public class JPEGProblem extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage window) throws Exception {
BufferedImage bi = getBufferedImage();
ImageView imgView = getFinalImageView(bi);
window.setScene(new Scene(new Pane(imgView)));
window.show();
}
private BufferedImage getBufferedImage() throws InterruptedException {
final java.awt.Image image = Toolkit.getDefaultToolkit().createImage("path\to\file");
final int[] RGB_MASKS = {0xFF0000, 0xFF00, 0xFF};
final ColorModel RGB_OPAQUE =
new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]);
PixelGrabber pg = new PixelGrabber(image, 0, 0, -1, -1, true);
pg.grabPixels();
int width = pg.getWidth(), height = pg.getHeight();
DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight());
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null);
return new BufferedImage(RGB_OPAQUE, raster, false, null);
}
private ImageView getFinalImageView(BufferedImage bi) throws Exception {
ImageView imgView = new ImageView(SwingFXUtils.toFXImage(bi, null));
imgView.setFitWidth(1024);
imgView.setFitHeight(756);
imgView.setRotate(180);
return imgView;
}
}
The problem here is that standard Image
api cannot read "broken" images, so we need to read it somehow differently. For this Toolkit.getDefaultToolkit().createImage() method can be used. Actually, the getBufferedImage
part was taken from this answer, so, all credits for this go there)
In getFinalImageView
method we simply transforms this BufferedImage
into javafx Image
and then into ImageView
using ImageIO class.
Result:
Note!
I can still observe some exceptions in logs, but they don't prevent this code from successful execution.
Imagecreatefromjpeg returns false even if image is exists
A combination of gd.jpeg_ignore_warning
and using the @
to suppress the error mentioned in the comment appears to work but for some inexplicable reason rotates the image by 90 degrees ~ perhaps the image was taken on a mobile?
<?php
ini_set ('gd.jpeg_ignore_warning', 1);
$src='c:/temp2/4cdf149b63d0ca0158f68357d8da371c_y.jpg';
$img=@imagecreatefromjpeg( $src );
header( 'Content-Type: image/jpeg' );
imagejpeg( $img );
imagedestroy( $img );
?>
Related Topics
PHP HTML Decoding Help - Converting: a 'Quote' Is <B>Bold</B>
Alternative to MySQLi_Fetch_All Needed
Appending a Value of a Variable to a Variable Name
PHP Datetime::Createfromformat in 5.2
Strpos() with Multiple Needles
Easiest Way to Implode() a Two-Dimensional Array
Replace the Last Comma with an & Sign
PHP File_Get_Contents() Behaves Differently to Browser
How to Subtract 24 Hour from Date Time Object in PHP
Nl2Br() Equivalent in JavaScript
How to Validate Non-English (Utf-8) Encoded Email Address in JavaScript and PHP
PHP Xpath - Find Element with a Value and Also Get Elements Before and After Element
How to Solve This "Warning: MySQLi_Connect(): (Hy000/1049): Unknown Database" Problem