简体   繁体   中英

How do I retrieve images within Postgres into Matlab using Java?

I have been given a bit of a strange task, there are around 1500-2000 jpeg images all of around 1-50kb in size. They are currently stored in a simple database I made with Postgres. It's been a long time since I used Matlab and Postgres heavily so any help or suggestions is really appreciated!

I need to get the images that are stored in the database, out of the database into Java. The last step is retrieve the image from Java into Matlab so that the image is stored in the same way in which the imread function works in Matlab. The imread function reads an image in and creates an by m by 3 matrix array of uint8 values which denote the pixel intensities of RGB.

Atm I have got the image in and out of the database in Java, currently storing the image in a bytea column data type. Is the best data type to use?

How can I get the data back out from the database, so that it is either the constructed jpeg image which I put in or is in the requested matrix array format?

Currently I do not understand the retrieved data. It is in a byte array of around 70,000 elements containing values between -128 to 128. Help!?!

Note: The database toolkit is unavailable to me

ANOTHER UPDATE: I have solved the problem related to the post regarding'UTF-8' encoding error.

If anyone stumbles upon this page, any answer posted will be tried as soon as I can! I really do appreciate your thoughts and answers. Thanks again.

When you say you have the image in a bytea column, how exactly is it stored? Is it storing the bytes of the JPEG file's contents, or an array of RGB pixel values, or something else? "Bytea" is just a binary string, which can store data in pretty much any format.

I'm assuming it's the JPEG contents. In that case what you can do is retrieve the jpeg contents via Java, save them to a temporary file, and call imread() on the temp file.

Those [-128,127] values are values of signed bytes Java. Even without the Database Toolbox, you can call regular JDBC or other Java code that uses it. The Java method you used to get those values - call it from Matlab (with your JAR on the classpath), and it should return that array as an int8 array, or something you can convert to one.

Given that in a Matlab variable named "bytes", you can write it out to a temp file with something like this.

file = [tempname() '.jpg'];
fid = fopen(file, 'wb');
fwrite(fid, bytes, 'int8');
fclose(fid);

By specifying 'int8' precision, I think you can skip the step of converting them to unsigned bytes, which is a more common convention. Writing int8s as 'int8' or uint8s as 'uint8' will produce the same file. If you do need to convert them to unsigned, use Matlab's typecast() function.

unsigned_bytes = typecast(bytes, 'uint8');

At that point you can call imread on the temp file and then delete it.

img = imread(file);
delete(file);

Problem solved :-)

I have managed to get the bytes stored within the bytea column within the database into a byte array. Then through creating a temp file ( using ByteArrayInputStream and Reader object to form a BufferedImage object which I write to a file) send this back into Matlab in an array.

Then process the data I retrieved and read from the temporary file in Matlab. Once the data is within Matlab all the temp files are deleted.

The code to process the ResultSet to create a temp image from a byte array received from the databases bytea column is shown below:

private static void processImageResultSet(ResultSet rs) throws SQLException, FileNotFoundException, IOException{

        int i = 0;                  //used as a count and to name various temp files
        while(rs.next()){           //loop through result sets

        byte[] b = rs.getBytes(1);                                 //the bytea column result
        String location = getFileName(rs.getString(2));            //the name of the jpg file
        ByteArrayInputStream bis = new ByteArrayInputStream(b);    //creates stream storing byts

        //To make individual names of temporary files unique the current time and date is stored
        SimpleDateFormat df = new SimpleDateFormat("'Date 'yyyy-MM-dd HH'H'-mm'M'-ss'secs'-SS'ms'"); //formats date string
        Calendar cal = Calendar.getInstance();                                //gets instance of calendar time
        String fileDate = df.format(cal.getTime());                           //gets the time and date as a String

        Iterator<?> readers = ImageIO.getImageReadersByFormatName("jpg");     //creates a reader object, that will read jpg codec compression format
        Object source = bis;                                                  //object to store stream of bytes from database
        ImageReader reader = (ImageReader) readers.next();                      
        ImageInputStream iis = ImageIO.createImageInputStream(source);        //creates image input stream from object source which stores byte stream

        reader.setInput(iis, true);             //sets the reader object to read image input stream

        ImageReadParam param = reader.getDefaultReadParam(); 
        Image image = reader.read(0, param);

        BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);   //creates buffered image

        Graphics2D g2 = bufferedImage.createGraphics();
        g2.drawImage(image, null, null);
        File imageFile = new File(location + " " + fileDate + " " + i + ".jpg"); //creates image file 
        ImageIO.write(bufferedImage, "jpg", imageFile);                          //writes buffered image object to created file

        i++;        //counts number of results from query within the ResultSet 
        }

    }

Do you have access to the Database Toolbox in MATLAB? If so, you should be able to directly connect to a PostgreSQL database using the DATABASE function and then import and export data using the FETCH function or the QUERYBUILDER GUI. This may be easier than first going through Java.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM