my application connects to a database in mysql using phpmyadmin and stores an image in the database, but my problem is when I download the image from the database and post the image on a imageview the image has a very low quality where also it's color is being afected too.
if I post the image directly on the database using phpmyadmin and then download the image using my app the image looks fine, but if I upload the image from my app and then i download it then the quality is bad.
the way to post the image is past the image to a byte[] and then uploading to the database that uses the type blob.
private byte[] imagenToByte(Image imagen) {
BufferedImage bufferimage = SwingFXUtils.fromFXImage(imagen, null);
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
ImageIO.write(bufferimage, "jpg", output );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte [] data = output.toByteArray();
return data;
}
can you help me please?
EDIT
#FXML
public void eventoBotonSeleccionarImagen() {
FileChooser imagenSeleccionada = new FileChooser();
FileChooser.ExtensionFilter filtroImagenjpg = new ExtensionFilter("Archivos *.jpg", "*.jpg");
FileChooser.ExtensionFilter filtroImagenJPG = new ExtensionFilter("Archivos *.JPG", "*.JPG");
File archivo = imagenSeleccionada.showOpenDialog(null);
try {
BufferedImage bufferedImage = ImageIO.read(archivo);
Image image = SwingFXUtils.toFXImage(bufferedImage, null);
imageViewMonstruo.setImage(image);
}
catch(Exception e) {
e.printStackTrace();
}
}
I found the answer to the question thanks to this
this question.
What I've done is changing from Blob to longblob in the database and adding png instead of jpg, the code result is this
private byte[] imagenToByte(Image imagen) {
BufferedImage bufferimage = SwingFXUtils.fromFXImage(imagen, null);
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
ImageIO.write(bufferimage, "png", output );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte [] data = output.toByteArray();
return data;
}
And finally it upload and download the images with the same quality
Related
I try to create a Gdx Texture with an image file located in a shared folder on my PC.
The code works well on desktop app (but it works as well without using SmbFile...), but crash on android app. I obtain "no such file or directory" error.
Does somebody knows how can we do that ?
Thank's !
public void create () {
Gdx.app.setLogLevel(Application.LOG_DEBUG);
batch = new SpriteBatch();
SmbFile file=null;
try {
file = new SmbFile("smb://***path to shared folder***/icon-152.png");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
FileHandle fileHandle;
fileHandle = new FileHandle(file.getUncPath());
img = new Texture(fileHandle); //***No such file or directory***
//img = new Texture(Gdx.files.external(file.getUncPath())); //***No such file or directory***
}
Add on :
I tried to copy the File in assets before to load it as a Texture. Still working fine on desktop app, but Stil having an error on android app : Java.io.FiliNotFound Exception.
public void create () {
Gdx.app.setLogLevel(Application.LOG_DEBUG);
batch = new SpriteBatch();
SmbFile file=null;
try {
file = new SmbFile("smb://***path to shared folder***/icon-152.png");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(file.getUncPath());
os = new FileOutputStream("test.png");
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
is.close();
os.close();
}
catch(java.io.IOException e){
Gdx.app.log("", e.getMessage()); //***Java.io.FileNotFound Exception***
}
img = new Texture("test.png"); //***No such file or directory***
}
Yes Nicolas,
I finaly did it by first copying the file in local. It is working on both android and desktop app.
If somebody is interested, the two functions loadFile and saveFile :
loadFile( "//***path to shared folder***/icon-152.png","icon-152.png");
saveFile("icon-152.png", "//HP2285/***path to shared folder***/icon-152.png");
}
public void loadFile(String smbFilePath, String fileName){
try {
SmbFile file = new SmbFile("smb:"+smbFilePath);
InputStream is = new SmbFileInputStream(file);
FileHandle fhd = Gdx.files.local(fileName);
OutputStream os = fhd.write(false);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
is.close();
os.close();
}
catch(Exception e){
}
}
public void saveFile(String fileName, String smbFilePath){
try {
SmbFile file = new SmbFile("smb:"+smbFilePath);
OutputStream os = new SmbFileOutputStream(file);
FileHandle fhs = Gdx.files.local(fileName);
InputStream is = fhs.read();
byte[] buffer = new byte[1024];
int length;
while ((length = is.read (buffer)) > 0) {
os.write(buffer, 0, length);
}
is.close();
os.close();
}
catch(Exception e){
}
}
i'm trying to upload an image to mysql database using phpmyadmin and despite the program works and stores the rest of the data the image is not stored correctly.
If I upload an image directly in phpmyadmin the image's size in type Blob it's 26.6 KB but if I try to uploading using javafx the image's size it's about 10 B so I think i'm not uploading correctly.
#Override
public void guardarMonstruo(MonstruoDTO monstruo) {
con= ConexionBDA.getInstance().getCon();
try {
if (con != null){
byte[] blob = imagenToByte(monstruo.getImagen());
System.out.println(blob.toString());
statement = con.createStatement();
statement.executeUpdate("INSERT INTO monstruos (Nombre,Habitat,Estado,ColaCercenable,DragonAnciano,DebilidadFuego,DebilidadAgua,Debilidadrayo,DebilidadHielo,DebilidadDraco,ImagenMonstruo) VALUES ('"+monstruo.getNombre()+"'"+","+"'"+monstruo.getHabitat()+"'"+","+"'"+monstruo.getEstado()+"'"+","+"'"+monstruo.getColaCercenable()+"'"+","+"'"+monstruo.getDragonAnciano()+"'"+","+"'"+monstruo.getDebilidadFuego()+"'"+","+"'"+monstruo.getDebilidadAgua()+"'"+","+"'"+monstruo.getDebilidadRayo()+"'"+","+"'"+monstruo.getDebilidadHielo()+"'"+","+"'"+monstruo.getDebilidadDraco()+"'"+","+"'"+blob+"');");
con.close();
statement.close();
}
}
catch(Exception e) {
e.printStackTrace();
}
}
And the method imagenToByte() is used to pass the image to byte is this:
private byte[] imagenToByte(Image imagen) {
BufferedImage bufferimage = SwingFXUtils.fromFXImage(imagen, null);
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
ImageIO.write(bufferimage, "jpg", output );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte [] data = output.toByteArray();
return data;
}
I don't know what i'm doing wrong, could you please help me?
You insert the result of the toString method to the query string which won't result in the desired outcome. Use PreparedStatement and set a Blob parameter instead:
try (PreparedStatement ps = con.prepareStatement("INSERT INTO monstruos (Nombre,Habitat,Estado,ColaCercenable,DragonAnciano,DebilidadFuego,DebilidadAgua,Debilidadrayo,DebilidadHielo,DebilidadDraco,ImagenMonstruo) VALUES (?,?,?,?,?,?,?,?,?,?,?)")) {
ps.setString(1, monstruo.getNombre());
ps.setString(2, monstruo.getHabitat());
ps.setString(3, monstruo.getEstado());
ps.setString(4, monstruo.getColaCercenable());
ps.setString(5, monstruo.getDragonAnciano());
ps.setString(6, monstruo.getDebilidadFuego());
ps.setString(7, monstruo.getDebilidadAgua());
ps.setString(8, monstruo.getDebilidadRayo());
ps.setString(9, monstruo.getDebilidadHielo());
ps.setString(10, monstruo.getDebilidadDraco());
// upload the data, not the toString result of the array
ps.setBlob(11, new SerialBlob(blob));
ps.executeUpdate();
}
I am using tess4j api for reading an image for numerics.
code as below:
public static void main(String[] args) {
// TODO Auto-generated method stub
final File imageFile = new File("C:\\Users\\goku\\Desktop\\myimage.png");
System.out.println("Image found");
final ITesseract instance = new Tesseract();
instance.setTessVariable("tessedit_char_whitelist", "0123456789");
instance.setDatapath("C:\\Users\\goku\\Downloads\\Tess4J");
instance.setLanguage("eng");
String result;
try {
result = instance.doOCR(imageFile);
System.out.println(result);
} catch (TesseractException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Image attached.
The program is reading the numerics as wrong. Not able to find the issue.
output:
1 1 3 251
regards,
Vasu
Rescaling the image to 300 DPI would get the correct result.
This is how to properly edit image with im4java (imagemagick) so it can be read with tess4j (tesseract):
private static File processImage(File img) throws IOException {
File newImg = File.createTempFile("asdf", ".png");
ImageMagickCmd cmd = new ImageMagickCmd("convert");
IMOperation op = new IMOperation();
op.addImage(img.getAbsolutePath());
op.strip().resample(300).colorspace("gray").autoLevel().threshold(35000).type("bilevel").depth(8).trim();
op.addImage(newImg.getAbsolutePath());
cmd.run(op);
return newImg;
}
It might be the trained data. I have used the trained data from the tesseract-ocr-w64-setup-v4.1.0.20190314.exe Windows binary, found at https://digi.bib.uni-mannheim.de/tesseract/, with the datapath set as below
instance.setDatapath("C:\\Program Files\\Tesseract-OCR\\tessdata");
I do get a warning about the resolution, but the result is correct:
471871882819
I use MySql db with images in blob and try to display them on my JSF page using PrimeFaces galleria. On my page I see this galleria, but images aren't displayed. I see only small green icons in a corner of every image. I get this problem only using DB. If my images are in my file system, everything will be OK. Can someone explain why I can't see images from DB? I wrote this code:
Galleria:
<p:galleria value="#{imagesView.images}" var="image" panelWidth="500" panelHeight="250" showCaption="true">
<p:graphicImage value="#{image}" alt="Image Description" title="Title"/>
</p:galleria>
ImagesView:
#ManagedBean
public class ImagesView {
private List<StreamedContent> images;
#PostConstruct
public void init() {
images = new ArrayList<>();
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
int itemId = Integer.parseInt(request.getParameter("item_id"));
for (int i = 1; i <= 2; i++) {
images.add(new GraphicImage().getImageFromDB(i, itemId)); //It's so simple because I need it just for test and that's all
}
}
public List<StreamedContent> getImages() {
return images;
}
}
GraphicImage:
#RequestScoped
class GraphicImage implements Serializable {
StreamedContent getImageFromDB(int id, int itemId) {
if (FacesContext.getCurrentInstance().getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
byte[] image = DBUtils.getImage(id, itemId);
return new DefaultStreamedContent(new ByteArrayInputStream(image), "image/jpg");
}
}
}
DBUtils method:
public static byte[] getImage(int id, int itemId) {
byte[] image = null;
ResultSet resultSet = null;
try (Connection connection = DataBase.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT content FROM images WHERE id = ? AND item_id = ?")) {
statement.setInt(1, id);
statement.setInt(2, itemId);
resultSet = statement.executeQuery();
resultSet.next();
image = resultSet.getBytes("content");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (resultSet != null) resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return image;
}
It's not how a p:graphicImage works. You're trying to display an image using a byte array while this tag requires an URL to the image (or a StreamedContent).
<p:graphicImage value="img/myImg.png" />
Now, you have 2 options (at least)
either create an image from your byte array (image data) and store
it somewhere where it's accessible by your web application. The value attribute should still contain an URL rather than a byte array.
don't store images in your DB, but rather store an image name (or
path to a image on the server ) (e.g. your DB will just constain
img001.png, img002 png etc and you know they're all inside, say, the img
folder on your server. Then, all you have to do is change the image URL.
<p:graphicImage value=#{imgUrl} />
Option 2 is actually recommended especially for large images, but even when your images are not large this method has the advantage of not having to convert images (byte arrays) to files.
In your HTML, this will be rendered as
<img src="img/img001.png" >
I tried to create a spreadsheet in Android. It sent a success message but it wasn't created.
I used the following code to create it:
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("application/vnd.google-apps.spreadsheet").setTitle("MonthExpense").build();
IntentSender intentSender = Drive.DriveApi
.newCreateFileActivityBuilder()
.setInitialMetadata(metadataChangeSet)
.setInitialDriveContents(result.getDriveContents())
.build(appobject.mGoogleApiClient);
try {
activity.startIntentSenderForResult(intentSender, 56, null, 0, 0, 0);
}
If I use any other mimetype it works correctly can anyone please guide me in the right way.
Edit
If i try any other mime type it works with out problem, So i guess the problem related with "application/vnd.google-apps.spreadsheet"
Try to change application/vnd.google-apps.spreadsheet to application/vnd.ms-excel
Create a WorkBook. This is the end of my working code
final private ResultCallback<DriveContentsResult> driveContentsCallback = new ResultCallback<DriveContentsResult>() {
#Override
public void onResult(final DriveContentsResult result) {
if (!result.getStatus().isSuccess()) {
showMessage("Error while trying to create new file contents");
return;
}
final DriveContents driveContents = result.getDriveContents();
// Perform I/O off the UI thread.
new Thread() {
#Override
public void run() {
//CREATE YOUR WORKBOOK HERE
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
wb.write(bos);
byte[] bytes = bos.toByteArray();
outputStream.write(bytes);
//WORKBOOK FILENAME
writer.write(fileName);
wb.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle(fileName)
.setMimeType("application/vnd.ms-excel")
.setStarred(true).build();
// create a file on root folder
Drive.DriveApi
.getRootFolder(getGoogleApiClient())
.createFile(getGoogleApiClient(), changeSet,
driveContents)
.setResultCallback(fileCallback);