Hi I'm trying to capture a picture using kotlin and registerForActivityResult but I allways get a blur image with no quality I've read several post but I can't understand how to work with my application. I'm using a fragment to call the camera. Any suggestions? Sorry for my bad english I've spent about the full week trying it works. And nothing. Thanks in advance
private var imagenUri: Uri? =null
val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
try {
val intent = result.data
intent!!.putExtra(MediaStore.EXTRA_OUTPUT, imagenUri)
val bitMap = intent?.extras?.get("data") as Bitmap
imagenUri= getImageUriFromBitmap(requireContext(),bitMap)
binding.ivImagen.setImageURI(imagenUri)
Toast.makeText(context, "la uri es: $imagenUri", Toast.LENGTH_SHORT).show()
} catch (e: java.lang.Exception){
Toast.makeText(context, "NO SE HA PODIDO ENCONTRAR IMAGEN", Toast.LENGTH_SHORT).show()}
}
}
binding.ibTomarFoto.setOnClickListener(){
startForResult.launch(Intent(MediaStore.ACTION_IMAGE_CAPTURE))
}
From the documentation:
public static final String ACTION_IMAGE_CAPTURE
Standard Intent action that can be sent to have the camera application capture an image and return it.
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field. This is useful for applications that only need a small image. If the EXTRA_OUTPUT is present, then the full-sized image will be written to the Uri value of EXTRA_OUTPUT.
So you need to add the EXTRA_OUTPUT extra to get a full-size image stored at a URI you supply. Otherwise you get a small image as a data payload in the result Intent (those bundles can't handle large objects).
It looks like you're already trying to do that, you've just added it to the wrong place - you need to add it to the Intent you call launch with, not the result one. It's a configuration option for the task you're launching!
So this should work:
binding.ibTomarFoto.setOnClickListener(){
startForResult.launch(
Intent(MediaStore.ACTION_IMAGE_CAPTURE).putExtra(MediaStore.EXTRA_OUTPUT, imagenUri)
)
}
And then remove the same putExtra line from your result-handler code (it doesn't do anything, but there's no point having it there)
Related
I would like to take a PowerPoint slide (the "source"), and insert it into another PowerPoint slide (the "target") that already contains some content, at a specific position in the source PowerPoint slide.
I've tried several ways to research code that does this, but I keep getting results for merging slides into PowerPoint presentations, which is not what I want. I want to take an existing slide and insert it into another, much like one would insert a picture into an existing slide.
I have code that another coworker wrote that clones all of the elements from the source slide, but it is convoluted and uses different code variations for different element types. Here is a representative sample of that code:
foreach (OpenXmlElement element in sourceSlide.CommonSlideData.ShapeTree.ChildElements.ToList())
{
string elementTypeName = element.GetType().ToString();
if (elementTypeName.EndsWith(".Picture"))
{
// Deep clone the element.
elementClone = element.CloneNode(true);
// Adjust the offsets so it is positioned correctly.
((Picture)elementClone).ShapeProperties.Transform2D.Offset.X += (Int64)shapeStruct.OffsetX;
((Picture)elementClone).ShapeProperties.Transform2D.Offset.Y += (Int64)shapeStruct.OffsetY;
// Get the shape tree that we're adding the clone to and append to it.
ShapeTree shapeTree = slideCard.CommonSlideData.ShapeTree;
shapeTree.Append(elementClone);
string rId = ((Picture)element).BlipFill.Blip.Embed.Value;
ImagePart imagePart = (ImagePart)slideInstProc.SlidePart.GetPartById(rId);
string contentType = imagePart.ContentType;
// Locate the same object we cloned over to the slide.
var blip = ((Picture)elementClone).BlipFill.Blip;
slidePart = slideCard.SlidePart;
try
{
ImagePart imagePart1 = slidePart.AddImagePart(contentType, rId);
imagePart1.FeedData(imagePart.GetStream());
}
catch (XmlException)
{
//Console.WriteLine(xe.ToString());
Console.WriteLine("Duplicate rId (" + rId + ")");
}
}
if (elementTypeName.EndsWith(".GroupShape"))
{
... etc
The code continues with an else-if ladder containing blocks of code for element type names ending with .GroupShape, .GraphicFrame, .Shape, and .ConnectionShape, concluding with a catchall else at the bottom.
The problem is this code doesn't process some types of objects properly. For one thing, it doesn't process drawings at all (perhaps because some of them originated from an older version of PowerPoint), and when it does, it does things like change the color of the drawing.
What I was hoping is that there was a more fundamental way (i.e. simpler, generic code) to embed a source PowerPoint slide into another, treating it like a single object, without looking at element types within the source PowerPoint specifically.
Alternatively, what would be the way to process drawings or images in ordinary "shapes" that don't identify themselves specifically as images?
This is the code that solved the specific problem I was describing above:
using A = DocumentFormat.OpenXml.Drawing;
foreach(A.BlipFill blipFill in shape.Descendants<A.BlipFill>())
{
string rId = blipFill.Blip.Embed.Value;
ImagePart imagePart = (ImagePart)slideInstProc.SlidePart.GetPartById(rId);
string contentType = imagePart.ContentType;
try
{
ImagePart imagePart1 = slidePart.AddImagePart(contentType, rId);
imagePart1.FeedData(imagePart.GetStream());
}
catch (XmlException)
{
Console.WriteLine("Duplicate rId (" + rId + ")");
}
}
Which, when applied to elementTypeName.EndsWith(".shape"); produces exactly the result I want.
For composing complete slides into a presentation (which doesn't require some of the generation mechanics that we do), OpenXmlPowerTools is a much better approach.
I have an image with longitude and latitude coordinates, can any one tell me how do i get it? I have tried
if (CrossMedia.Current.IsPickPhotoSupported)
{
MediaFile photoPicked = await CrossMedia.Current.PickPhotoAsync();
if (photoPicked != null)
{
//await DisplayAlert("Photo Location", photoPicked.Path, "OK");
//path = photoPicked.Path;
using (Stream streamPic = photoPicked.GetStream())
{
var picInfo = ExifReader.ReadJpeg(streamPic);
ExifOrientation orientation = picInfo.Orientation;
//MainImage123.Source = ImageSource.FromStream(() => photoPicked.GetStream());
latitude = picInfo.GpsLatitude;
longitude = picInfo.GpsLongitude;
var filepath = photoPicked.AlbumPath;
var filepath1 = photoPicked.Path;
}
}
}
It works when I picked photo and trying to get its coordinates, but I have to take multiple photos from image gallery and find its coordinates.
does any one know how to read image geo coordinates? please help me.
You can use the ExifLib.PCL Nuget Package to read an image metada, by viewing your "code sample", i think you are using the Plugin.Media to take images/get images from the galery, be sure to use SaveMetaData = true when taking an photo from your app.
Once you have set the SaveMetaData to true, use the ExifLib to obtain the MetaData like this:
MediaFile photo;
using (Stream streamPic = photo.GetStream())
{
var picInfo = ExifReader.ReadJpeg(streamPic);
double lat = picInfo.GpsLatitude;
double lon = picInfo.GpsLongitude;
}
Also, as a plus, you have even more info on the photo (date taken, author, size, etc.).
UPDATE:
After Reading it again, it seems that the problem is that you are not able to pick multiple images from the galery, and NOT being able to get the lat and lon from the photos. At the moment, Plugin.Media doesn't support multi-picking.
Your question was unclear however - I think you are trying to make it work with multiple images together. How you can be able to pick multiple images together?
The plugin "CrossMedia" doesn't support picking up multiple images.
Your solution requires a lot of work to be done to be able to Pickup multiple images at once. So Follow this nice step-by-step tutorial here:
https://xamgirl.com/select-multiple-images-from-gallery-in-xamarin-forms/
With above you will be able to get all the images you need at once.
After you get List, all you have to do is to loop through those images and call your existing code.
I am using the following Java code to read a Dicom image, trying to convert it later to JPEG file. When the reading happens in the line
tempImage = ImageIO.read(dicomFile);
, the returned image either has an image type of 10 or something else, like 0 or 11. The problem here is that the reading happens sporadically. Sometimes the returned image type is 10, and sometimes it is not.
When the returned image type is 10, the writing of the converted JPEG file succeeds and returns true and I get my JPEG file. However, when the returned image type is not 10, the writing fails and returns false, and doesn't produce any file. This is the statement I am using for writing:
writerReturn = ImageIO.write(image, "jpeg", new File(tempLocation + studyId + File.separator + seriesUID + File.separator + objectId + thumbnail+ ".jpeg"));
I have spent long time trying to figure out why this sporadic behaviour is happening but couldn't reach to anything. Could you please help?
I am guessing the issue is that your input image is 16bits while I am sure your code only accept 8bits input. You cannot write out using the so-called usual JPEG 8bits lossy format unless you transform your 16bits input.
On my box here is what I see:
$ gdcminfo 1.2.840.113619.2.67.2200970061.29232060605151433.387
MediaStorage is 1.2.840.10008.5.1.4.1.1.1.1 [Digital X-Ray Image Storage - For Presentation]
TransferSyntax is 1.2.840.10008.1.2.4.90 [JPEG 2000 Image Compression (Lossless Only)]
NumberOfDimensions: 2
Dimensions: (1887,1859,1)
SamplesPerPixel :1
BitsAllocated :16
BitsStored :14
HighBit :13
PixelRepresentation:0
ScalarType found :UINT16
PhotometricInterpretation: MONOCHROME2
PlanarConfiguration: 0
TransferSyntax: 1.2.840.10008.1.2.4.90
Group 0x6000
Rows 1859
Columns 1887
NumberOfFrames 0
Description
Type G
Origin[2] 1,1
FrameOrigin 0
BitsAllocated 1
BitPosition 0
Origin: (0,0,0)
Spacing: (0.187429,0.187429,1)
DirectionCosines: (1,0,0,0,1,0)
Rescale Intercept/Slope: (0,1)
Orientation Label: AXIAL
So if you want to convince yourself you could extract the encapsulated JPEG 2000 bytestream:
$ gdcmraw 1.2.840.113619.2.67.2200970061.29232060605151433.387 bug.j2k
$ file bug.j2k
bug.j2k: JPEG 2000 codestream
I was able to open the generated bug.j2k using either IrfanView and kdu_show, but as you can see the image is very dark (only the lower bits are read).
From extra information in the comments, we have discovered that the application is running in a Glassfish server, and that there are two ImageIO plugins installed, both capable of reading DICOM images. The problem is not really related to reading, but sometimes writing the decoded image to JPEG fails.
The service providers for mentioned plugins are org.dcm4cheri.imageio.plugins.DcmImageReaderSpi and
org.dcm4che2.imageioimpl.plugins.dcm.DicomImageReaderSpi, but only the latter (DicomImageReaderSpi) seems to work. This is because it produces an 8 bits per sample BufferedImage, which is what the JPEGImageWriter is able to write (the DcmImageReaderSpi creates a 16 bit per sample image, which can't be written as a JFIF JPEG and thus unsupported by the JPEGImageWriter).
Because of the (by default) unspecified (read: unpredictable) order of ImageIO plugins, the result is that sometimes you get the 8 bps version and sometimes the 16 bit version of the image, and the end result is that sometimes the conversion won't work.
Now, the good news is that we can set an explicit order of ImageIO plugins, or we can unregister plugins at runtime, to get a stable predictable result. What is the better of these options, depends on wether there are other code on your server that depends on the undesired plugin or not. If you don't need it, unregister it.
The code below shows both of the above options:
// Get the global registry
IIORegistry registry = IIORegistry.getDefaultInstance();
// Lookup the known providers
ImageReaderSpi goodProvider = lookupProviderByName(registry, "org.dcm4che2.imageioimpl.plugins.dcm.DicomImageReaderSpi");
ImageReaderSpi badProvider = lookupProviderByName(registry, "org.dcm4cheri.imageio.plugins.DcmImageReaderSpi");
if (goodProvider != null && badProvider != null) {
// If both are found, EITHER
// order the good provider BEFORE the bad one
registry.setOrdering(ImageReaderSpi.class, goodProvider, badProvider);
// OR
// un-register the bad provider
registry.deregisterServiceProvider(badProvider);
}
// New and improved (shorter) version. :-)
private static <T> T lookupProviderByName(final ServiceRegistry registry, final String providerClassName) {
try {
return (T) registry.getServiceProviderByClass(Class.forName(providerClassName));
}
catch (ClassNotFoundException ignore) {
return null;
}
}
You should also make sure you run this code only once, for a container-based application, a good time is at application context start-up.
With the above solution, ImageIO.read(...) will always use the good plugin, and ImageIO.write(...) will work as expected.
I'm using the JPointCloud sample app, and modifying it a little bit:
In JPointCloud.java : SetUpExtrinsics(), I added:
TangoPoseData depth2devicePose = new TangoPoseData();
framePair.baseFrame = TangoPoseData.COORDINATE_FRAME_DEVICE;
framePair.targetFrame = TangoPoseData.COORDINATE_FRAME_CAMERA_DEPTH;
try {
depth2devicePose = mTango.getPoseAtTime(0.0, framePair);
} catch (TangoErrorException e) {
Toast.makeText(getApplicationContext(), R.string.TangoError,
Toast.LENGTH_SHORT).show();
The application crashes when reaching the line:
depth2devicePose = mTango.getPoseAtTime(0.0, framePair);
I tried with other combinations of frame, but each time COORDINATE_FRAME_CAMERA_DEPTH is included, the app crashes.
Did I forget something ? Maybe to ask some kind of special permission for the depth camera ?
It indeed crashes on me as well.
However, according to the Java pointcloud example code (extrinsic query part), the correct way of querying the DEPTH_CAMERA w.r.t(with respect to) DEVICE transformation is using 'the inverse of DEVICE w.r.t IMU' multiply 'CAMAER w.r.t IMU', which is:
deive_T_camera = inverse(imu_T_device) * imu_T_camera
Also, note that the color camera, depth camera and camera are the same camera on the hardware level, so they actually share the same extrinsic.
Hope this helps.
Edit: the crashes actually throw an com.google.atap.tangoservice.TangoInvalidException. This might just be a frame pair not supported from API level, as mentioned before, the suggested way would be using other two matrices to compose the desired matrix in this case..
I'm getting a CVImageBufferRef from my AVCaptureSession, and I'd like to take that image buffer and upload it over the network. To save space and time, I would like to do this without rendering the image into a CIImage and NSBitmapImage, which is the solution I've seen everywhere (like here: How can I obtain raw data from a CVImageBuffer object).
This is because my impression is that the CVImageBuffer might be compressed, which is awesome for me, and if I render it, I have to uncompress it into a full bitmap and then upload the whole bitmap. I would like to take the compressed data (realizing that a single compressed frame might be unrenderable later by itself) just as it sits within the CVImageBuffer. I think this means I want the CVImageBuffer's base data pointer and its length, but it doesn't appear there's a way to get that within the API. Anybody have any ideas?
CVImageBuffer itself is an abstract type. Your image should be an instance of either CVPixelBuffer, CVOpenGLBuffer, or CVOpenGLTexture. The documentation for those types lists the functions you can use for accessing the data.
To tell which type you have use the GetTypeID methods:
CVImageBufferRef image = …;
CFTypeID imageType = CFGetTypeID(image);
if (imageType == CVPixelBufferGetTypeID()) {
// Pixel Data
}
else if (imageType == CVOpenGLBufferGetTypeID()) {
// OpenGL pbuffer
}
else if (imageType == CVOpenGLTextureGetTypeID()) {
// OpenGL Texture
}