Skip to content
Snippets Groups Projects
Commit ad40cb0e authored by Stian Fjæran Mogen's avatar Stian Fjæran Mogen Committed by Mads Lundegaard
Browse files

Added image search functionality

Following things where added:

1. Created ImageService;
createImage
getImageFromUser
getAllImages

2. Created MetadataRepository
Used TagRepository as inspiration

3. Updated ImageRepository
added IMAGE_FIND_BY_USERNAME
findAllByUsername

4. Updated Image
added NamedQuery selecting username from Image table in DB
parent c9432c92
No related branches found
No related tags found
1 merge request!104Weekly merge to Master
Showing with 302 additions and 113 deletions
......@@ -28,19 +28,22 @@ public class GeoLocation {
private Metadata metadata;
@NotBlank (message = "Altitude may not be blank")
private String altitude;
private String latitude;
@NotBlank (message = "Longitude may not be blank")
private String longitude;
public GeoLocation() {
}
/**
* Creates constructor for geolocation that takes in each parameter
*
* @param altitude
*
* @param latitude
* @param longitude
*/
public GeoLocation(String altitude, String longitude){
this.altitude = altitude;
public GeoLocation(String latitude, String longitude){
this.latitude = latitude;
this.longitude = longitude;
}
......@@ -48,8 +51,8 @@ public class GeoLocation {
return geoLocationId;
}
public String getAltitude() {
return altitude;
public String getLatitude() {
return latitude;
}
public String getLongitude() {
......@@ -60,8 +63,8 @@ public class GeoLocation {
this.geoLocationId = geoLocationId;
}
public void setAltitude(String altitude) {
this.altitude = altitude;
public void setLatitude(String altitude) {
this.latitude = altitude;
}
public void setLongitude(String longitude) {
......
......@@ -14,6 +14,10 @@ import java.util.List;
@Entity
@Table(name = "image")
@NamedQueries({
@NamedQuery(name="Image.findAllByUsername",
query = "SELECT ia from Image ia WHERE ia.user.username = :username")
})
public class Image {
@Id
......@@ -21,7 +25,10 @@ public class Image {
private Long id;
@ManyToMany
private List<ImageAlbum> imageAlbums = new ArrayList<>();;
private List<ImageAlbum> imageAlbums = new ArrayList<>();
@ManyToMany
private List<Tag> tags = new ArrayList<>();
@ManyToOne
private User user;
......@@ -49,6 +56,7 @@ public class Image {
this.user = user;
this.metadata = metadata;
this.path = path;
this.tags = new ArrayList<>();
}
public Long getId() {
......@@ -83,7 +91,15 @@ public class Image {
return imageAlbums;
}
public Metadata getMetadata() {
public void addTag(Tag tag){
tags.add(tag);
}
public List<Tag> getTags() {
return tags;
}
public Metadata getMetadata() {
return metadata;
}
......@@ -95,6 +111,7 @@ public class Image {
return path;
}
/**
* Add this image in the given image album.
*
......
......@@ -41,7 +41,6 @@ public class Metadata {
this.histogram = histogram;
}
public Long getMetadataId() {
return metadataId;
}
......
package NTNU.IDATT1002.models;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
* Tag model
* @author Stian Mogen
*/
/**
* Creates table named tag
*/
......
package NTNU.IDATT1002.repository;
import NTNU.IDATT1002.models.Image;
import javax.persistence.EntityManager;
import javax.persistence.EntityManager;
import java.util.List;
/**
......@@ -16,6 +19,11 @@ import NTNU.IDATT1002.models.Image;
public class ImageRepository extends GenericRepository<Image, Long> {
/**
* Mapping to @NamedQuery 'find all image albums by users username' defined in {@link Image}
*/
public static final String IMAGE_FIND_BY_USERNAME = "ImageAlbum.findAllByUsername";
/**
* Constructor to inject {@link EntityManager} dependency.
*
......@@ -25,6 +33,18 @@ public class ImageRepository extends GenericRepository<Image, Long> {
super(entityManager);
setClassType(Image.class);
}
/**
* Retrieves all image albums of the user with the given username.
*
* @param username the username to query for
* @return the list of the users image albums.
*/
public List<Image> findAllByUsername(String username) {
return entityManager.createNamedQuery(IMAGE_FIND_BY_USERNAME, Image.class)
.setParameter("username", username)
.getResultList();
}
}
......
package NTNU.IDATT1002.repository;
import NTNU.IDATT1002.models.Metadata;
import javax.persistence.EntityManager;
import java.util.Optional;
/**
* Tag Repository.
*
* Implementation of {@link GenericRepository} which supports regular Create, Read, Update and Delete operations.
* @author Stian Mogen, Eirik Steira
* @version 1.0 22.03.20
* @see NTNU.IDATT1002.repository.GenericRepository
*/
public class MetadataRepository extends GenericRepository<Metadata, Long> {
/**
* Constructor to inject {@link EntityManager} dependency and sets the class type to {@link Metadata}
*
* @param entityManager the entity manager to utilize
*/
public MetadataRepository(EntityManager entityManager) {
super(entityManager);
setClassType(Metadata.class);
}
/**
* Retrieves a tag if found and creates it if not.
*
* @param metadata the tag to retrieve
* @return the tag if found, else the newly created one.
*/
public Optional<Metadata> findOrCreate(Metadata metadata) {
Optional<Metadata> foundMetadata = findById(metadata.getMetadataId());
if (foundMetadata.isPresent())
return foundMetadata;
return save(metadata);
}
}
\ No newline at end of file
package NTNU.IDATT1002.service;
import NTNU.IDATT1002.models.*;
import NTNU.IDATT1002.repository.ImageAlbumRepository;
import NTNU.IDATT1002.repository.ImageRepository;
import NTNU.IDATT1002.repository.TagRepository;
import NTNU.IDATT1002.repository.MetadataRepository;
import NTNU.IDATT1002.service.filters.ImageAlbumFilter;
import NTNU.IDATT1002.service.filters.ImageFilter;
import NTNU.IDATT1002.utils.ImageUtil;
import NTNU.IDATT1002.utils.MetaDataExtractor;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.io.File;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Image service
* @author Stian Mogen, Eirik Steira, Madslun
* @version 1.0 22.03.2020
*/
public class ImageService {
private ImageRepository imageRepository;
private MetadataRepository metadataRepository;
private TagRepository tagRepository;
/**
* Inject entity manager instance to the repositories.
*/
public ImageService() {
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("ImageApplication");
EntityManager entityManager = entityManagerFactory.createEntityManager();
this.imageRepository = new ImageRepository(entityManager);
this.metadataRepository = new MetadataRepository(entityManager);
this.tagRepository = new TagRepository(entityManager);
}
/**
* Creates a new image from the input File
*
* @param user the user of the image
* @param file the file uploaded
* @return Optional containing the saved image
*/
public Optional<Image> createImage(User user, File file) {
Image image = new Image();
byte[] bFile = ImageUtil.convertToBytes(file.getPath());
Metadata metadata = MetaDataExtractor.assembleMetaData(file);
//TODO: Unsure what to do with imageAlbum
image.setRawImage(bFile);
image.setUser(user);
image.setUser(null);
image.setMetadata(metadata);
image.setPath(file.getPath());
return imageRepository.save(image);
}
/**
* Finds each picture belonging to a specific user
* @param user
* @return a list with all pictures from a user
*/
public List<Image> getImageFromUser(User user) {
return imageRepository.findAllByUsername(user.getUsername());
}
/**
* Retrieves all images.
*
* @return list of all images.
*/
public List<Image> getAllImages() {
return imageRepository.findAll();
}
/**
* Adds the given tag to the given image album.
*
* @param image the image album to add the tag to
* @param tag the tag to add
* @return the updated image album
*/
public Optional<Image> addTagToImage(Image image, Tag tag) {
Image foundImage = imageRepository.findById(image.getId())
.orElseThrow(IllegalArgumentException::new);
Tag foundTag = tagRepository.findOrCreate(tag)
.orElseThrow(IllegalArgumentException::new);
foundImage.addTag(foundTag);
return imageRepository.save(foundImage);
}
/**
* Search all images by tags specified in {@link ImageFilter#filter(String)}.
*
* @param query the query to filter by
* @return list of images matching the query
*/
//This search method is for futureproofing, when we will search using additional parameters than just tags
public List<Image> searchImageAlbums(String query) {
List<Image> allImages = imageRepository.findAll();
return allImages.stream()
.filter(ImageFilter.filter(query))
.collect(Collectors.toList());
}
}
package NTNU.IDATT1002.service.filters;
import NTNU.IDATT1002.models.Image;
import java.util.function.Predicate;
/**
* Image Album Filter. Class to filter an image album by title, description and tag names.
*
* @author Stian Mogen
* @version 1.0 22.03.20
*/
public class ImageFilter {
/**
* Image filter can filter an album by tags
* Uses method filterByTags
* @param query the query to filter by
* @return predicate chaining the image album filter components.
*/
public static Predicate<Image> filter(String query) {
return filterByTags(query);
}
/**
* Filters images based on tag
* @param tagName
* @return predicate to apply
*/
private static Predicate<Image> filterByTags(String tagName){
return image -> image.getTags().stream()
.anyMatch(tag -> tag.getName().equalsIgnoreCase(tagName));
}
}
package NTNU.IDATT1002.utils;
import NTNU.IDATT1002.models.GeoLocation;
import NTNU.IDATT1002.models.Histogram;
import NTNU.IDATT1002.models.Image;
import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
......@@ -10,62 +13,15 @@ import com.drew.metadata.exif.*;
import com.drew.metadata.jpeg.JpegDirectory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
public class MetaDataExtractor {
private final File image;
public MetaDataExtractor(File image) {
this.image = image;
}
/**
* Extracts all data possible for a image
*
* @return
* @throws ImageProcessingException
* @throws IOException
*/
public String getAll() throws ImageProcessingException, IOException {
Metadata metadata = ImageMetadataReader.readMetadata(this.image);
String text = "";
for (Directory d : metadata.getDirectories()) {
for (Tag t : d.getTags()) {
text += t.toString() + " | ";
}
}
text += "\n";
return text;
}
/**
* Returns a string with the image dimension
*
* @return
* @throws ImageProcessingException
* @throws IOException
* @throws MetadataException
*/
private String getDimension() throws ImageProcessingException, IOException, MetadataException {
try {
String dimension = "Dimension: ";
Metadata metadata = ImageMetadataReader.readMetadata(this.image);
JpegDirectory jpeg = metadata.getFirstDirectoryOfType(JpegDirectory.class);
dimension += jpeg.getImageHeight();
dimension += "x";
dimension += jpeg.getImageWidth();
return dimension;
} catch (NullPointerException e) {
}
return "No dimension found";
}
/**
* Returns a string with the GPS position
*
......@@ -74,35 +30,53 @@ public class MetaDataExtractor {
* @throws IOException
* @throws MetadataException
*/
private String getGPS() throws ImageProcessingException, IOException, MetadataException {
try {
String gps = "";
private static GeoLocation getGPS(File file) throws ImageProcessingException, IOException, MetadataException {
String gps = "";
String latitude = "";
String longitude = "";
GeoLocation geoLocation = new GeoLocation("0", "0");
Metadata metadata = ImageMetadataReader.readMetadata(this.image);
try {
Metadata metadata = ImageMetadataReader.readMetadata(file);
GpsDirectory gpspos = metadata.getFirstDirectoryOfType(GpsDirectory.class);
gps += "GPS position: " + gpspos.getGeoLocation();
gps += gpspos.getGeoLocation();
String[] pos = gps.split(", ");
latitude = pos[0];
longitude = pos[0];
return gps;
geoLocation.setLatitude(latitude);
geoLocation.setLongitude(longitude);
} catch (NullPointerException e) {
e.printStackTrace();
}
return "No GPS information found";
return geoLocation;
}
/**
* Returns all predetermined metadata as an ArrayList
* @return
* @throws IOException
* @throws MetadataException
* @throws ImageProcessingException
*/
public ArrayList<String> getNecessary() throws IOException, MetadataException, ImageProcessingException {
ArrayList<String> information = new ArrayList<String>();
public static Histogram getHistorgram(File file) throws ImageProcessingException, IOException {
String text = "";
Metadata metadata = ImageMetadataReader.readMetadata(file);
Histogram histogram = new Histogram();
information.add(getGPS());
information.add(getDimension());
for(Directory d : metadata.getDirectories()) {
for (Tag t : d.getTags()) {
text += t.toString() + " | ";
}
}
histogram.setData(text);
return histogram;
}
return information;
public static NTNU.IDATT1002.models.Metadata assembleMetaData(File file) {
NTNU.IDATT1002.models.Metadata metadata = new NTNU.IDATT1002.models.Metadata();
try {
metadata.setGeoLocation(getGPS(file));
metadata.setHistogram(getHistorgram(file));
}
catch (Exception e) {
e.printStackTrace();
}
return metadata;
}
}
\ No newline at end of file
}
package NTNU.IDATT1002.utils;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.MetadataException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
public class MultiplePhotos {
private final ArrayList<File> images;
public MultiplePhotos(ArrayList<File> images) {
this.images = images;
}
private ArrayList<String> extractAll() throws ImageProcessingException, MetadataException, IOException {
ArrayList<String> data = new ArrayList<String>();
for(File i : this.images) {
MetaDataExtractor e = new MetaDataExtractor(i);
String n = e.getAll().toString();
data.add(n);
}
return data;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment