Сохранить изображение в Hbase с потерей метаданных и Exif

Загрузив изображение в hbase с помощью программы Java, после извлечения изображения я обнаружил, что разница в размере файла в конечном итоге увеличилась, и большая часть потери Exif и метаданных (данные о местоположении GPS, сведения о камере и т. д.)

Код :

public ArrayList<Object> uploadImagesToHbase(MultipartFile uploadedFileRef){
    byte[] bytes =uploadedFileRef.getBytes();
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ImageIO.write(image, "jpg", outputStream);
    HBaseAdmin admin = new HBaseAdmin(configuration);
    HTable table = new HTable(configuration, "sample");
    Put image = new Put(Bytes.toBytes("1"));
    image.add(Bytes.toBytes("DataColumn"), Bytes.toBytes(DataQualifier), bytes);
    table.put(image);

Как сохранить и получить изображение без каких-либо изменений/потерь?


person Sharavanakumaar Murugesan    schedule 30.04.2016    source источник
comment
как вы его сохранили и какой у вас код для его хранения?   -  person Whitefret    schedule 30.04.2016
comment
Это не имеет ничего общего с hadoop или hbase. Изображение отличается, потому что вы перекодировали его в первых трех строках кода. Вместо этого вам нужно загрузить изображение из файла в байтовый буфер без использования ImageIO.   -  person gudok    schedule 01.05.2016
comment
Хорошо. Теперь я изменил свой код как byte[] bytes = uploadedFileRef.getBytes();, где uploadedFileRef=Multipartfile   -  person Sharavanakumaar Murugesan    schedule 01.05.2016
comment
Код, который вы разместили, кажется очень фиктивным, с несколькими переменными с именами image и т. д. Но в любом случае @gudok верен, просто сохраните массив bytes байтов непосредственно в своей базе данных, и все будет в порядке.   -  person Harald K    schedule 01.05.2016
comment
Можете ли вы перепроверить свой код генерации массива байтов с помощью mkyong.com/java/how-to-convert-byte-to-bufferedimage-in-java ?   -  person Ram Ghadiyaram    schedule 02.05.2016
comment
@RamPrasadG Вы упускаете суть. ImageIO или BufferedImage здесь не нужны. Он должен просто хранить байты в базе данных.   -  person Harald K    schedule 02.05.2016
comment
Нет, я был не в стороне, на самом деле, я просил его перепроверить, как он создал этот массив байтов для хранения в Hbase. то есть imageInByte = baos.toByteArray(); из кода, который был приведен в ссылке.   -  person Ram Ghadiyaram    schedule 02.05.2016
comment
Как уже заявил @gudok, ImageIO в данном случае является проблемой, а не лекарством. Ссылка, размещенная RamPrasad G, не записывает метаданные, поэтому она не может решить проблему OP. Если gudok хочет опубликовать ответ, я с радостью удалю свой и проголосую за него.   -  person Harald K    schedule 02.05.2016


Ответы (2)


Попробуйте использовать SerializationUtils из Apache Commons Lang.

Ниже приведены методы

static Object   clone(Serializable object)  //Deep clone an Object using serialization.
static Object   deserialize(byte[] objectData) //Deserializes a single Object from an array of bytes.
static Object   deserialize(InputStream inputStream)  //Deserializes an Object from the specified stream.
static byte[]   serialize(Serializable obj) //Serializes an Object to a byte array for storage/serialization.
static void serialize(Serializable obj, OutputStream outputStream) //Serializes an Object to the specified stream.

При сохранении в hbase вы можете сохранить байт [], который был возвращен из сериализации. При получении объекта вы можете ввести приведение к соответствующему объекту, например: File object, и можете вернуть его.

person Ram Ghadiyaram    schedule 01.05.2016
comment
В OP уже есть byte[] bytes из MultipartFile. Ему не нужно ничего (повторно) сериализовать. - person Harald K; 02.05.2016
comment
@haraIdK: я знаю, что его способ сериализации и преобразования в массив байтов не работает. Я прошу его попробовать другой подход, отличный от того, что он сделал, чтобы проверить, работает он или нет. Похоже, вы неправильно поняли мое намерение - person Ram Ghadiyaram; 02.05.2016

Скорее всего, вы просто слишком усложняете. :-)

Причина, по которой вы теряете Exif и другие метаданные, заключается в том, что ImageIO удобные методы ImageIO.read(...) и ImageIO.write(...) не сохраняют метаданные. Хорошая новость в том, что они не нужны.

Поскольку у вас уже есть данные изображения из MultipartFile, вам следует просто сохранить эти данные (массив байтов) в базе данных, и вы сохраните в точности то, что загрузил пользователь. Никакой разницы в размере файла, и метаданные останутся нетронутыми.

Ваш код выше не компилируется для меня, и я не эксперт HBase, поэтому я просто опускаю это (поскольку вы уже смогли сохранить изображение, чтобы увидеть разницу в размере/качестве и потерю метаданных, я предполагаю, что вы знаю как это сделать :-) ). Но вот основы:

public ArrayList<Object> uploadImagesToHbase(MultipartFile uploadedFileRef) {
    byte[] bytes = uploadedFileRef.getBytes();

    // Store the above "bytes" byte array in HBase *as is* (no ImageIO)
}
person Harald K    schedule 02.05.2016
comment
Да, вы были правы, изначально я использовал библиотеку imageIo и потерял все метаданные. Теперь сохранение и извлечение в виде массива байтов. Теперь вопросы решены. Спасибо - person Sharavanakumaar Murugesan; 03.05.2016