A BLOB
- это двоичные данные - они по сути не имеют формата (такого как JPEG / PNG / BMP) и, как таковые, не являются неявно изображением, и спрашивать, какова его ширина / высота, не имеет смысла.
Что вам нужно сделать, это взять двоичные данные (BLOB) из их (неизвестного) двоичного формата (например, JPG / PNG / BMP / и т. Д.) И использовать программу чтения изображений для считывания измерений из мета-файла-data (поэтому вам не нужно загружать весь файл).
Вы можете написать класс Java, который имеет функцию, которая принимает BLOB / двоичный поток и формат изображения, а затем использует ImageIO или ImageReader & ImageInputStream (например, в качестве первых совпадений, которые я обнаружил при чтении изображений из двоичных данных; будут другие решения / библиотеки), извлеките измерения из заголовка[ 1 , 2 ] и верните его.
Затем, чтобы загрузить этот класс в базу данных Oracle, используйте утилиту loadjava
или CREATE OR REPLACE AND COMPILE JAVA SOURCE
( пример для распаковки сжатой строкихранится в Oracle BLOB).
Затем напишите функцию SQL, чтобы обернуть реализацию Java, чтобы она передавала BLOB в функцию Java и возвращала ширину или высоту (или структуру, содержащую оба значения).
Java-код :
import java.io.IOException;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
public class ImageMetaDataReader {
public static Integer getHeight(
final Blob blob,
final String fileType
) throws SQLException
{
Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix( fileType );
while(iter.hasNext())
{
ImageReader reader = iter.next();
try
{
ImageInputStream stream = new MemoryCacheImageInputStream( blob.getBinaryStream() );
reader.setInput(stream);
return reader.getHeight(reader.getMinIndex());
} catch ( IOException e ) {
} finally {
reader.dispose();
}
}
return null;
}
public static Integer getWidth(
final Blob blob,
final String fileType
) throws SQLException
{
Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix( fileType );
while(iter.hasNext())
{
ImageReader reader = iter.next();
try
{
ImageInputStream stream = new MemoryCacheImageInputStream( blob.getBinaryStream() );
reader.setInput(stream);
return reader.getWidth(reader.getMinIndex());
} catch ( IOException e ) {
} finally {
reader.dispose();
}
}
return null;
}
}
Тестирование :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.SQLException;
public class MockBlob implements Blob {
private final File file;
public MockBlob(
final File file
)
{
this.file = file;
}
@Override
public long length() throws SQLException {
return file.length();
}
@Override
public InputStream getBinaryStream() throws SQLException {
try
{
return new FileInputStream( this.file );
}
catch( FileNotFoundException e )
{
throw new SQLException( e.getMessage() );
}
}
@Override public byte[] getBytes(long pos, int length) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
@Override public long position(byte[] pattern, long start) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
@Override public long position(Blob pattern, long start) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
@Override public int setBytes(long pos, byte[] bytes) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
@Override public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
@Override public OutputStream setBinaryStream(long pos) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
@Override public void truncate(long len) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
@Override public void free() throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
@Override public InputStream getBinaryStream(long pos, long length) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); }
}
import java.io.File;
import java.sql.Blob;
import java.sql.SQLException;
public class ImageTest {
public static void main(
final String[] args
) throws SQLException
{
File file = new File( "/path/to/test.png" );
Blob blob = new MockBlob( file );
System.out.println(
"height: "
+ ImageMetaDataReader.getHeight( blob, "png" )
);
System.out.println(
"width: "
+ ImageMetaDataReader.getWidth( blob, "png" )
);
}
}
SQL :
CREATE AND COMPILE JAVA SOURCE NAMED "ImageMetaDataReader" AS
<the java code from above>
/
CREATE FUNCTION getImageHeight(
file IN BLOB,
fileType IN VARCHAR2
) RETURN NUMBER
AS LANGUAGE JAVA
name 'ImageMetaDataReader.getHeight( java.sql.Blob, String) return Integer';
/
CREATE FUNCTION getImageWidth(
file IN BLOB,
fileType IN VARCHAR2
) RETURN NUMBER
AS LANGUAGE JAVA
name 'ImageMetaDataReader.getWidth( java.sql.Blob, String) return Integer';
/
(Код не проверен в базе данных Oracle, так как в данный момент у меня нет экземпляра для передачи.)