Strapi: VipsJpeg: Premature end of input file error - file-upload

Problem:
When uploading an image from Strapi (the Media Library (UI)) it shows me the error: VipsJpeg: Premature end of input file.
I tried to change the format from jpg to png but it still shows the same error. On the other hand, I was testing with other images (jpg/png format). and it uploads correctly.
I would like to know the reason for the error, and if there is any solution.
I will appreciate your answer
Uploading image to strapi: Media Library
Image Info
JPEG image - 19 KB
Dimensions: 750 × 938
Error:
Error: VipsJpeg: Premature end of input file
config/plugins.js
Default configuration, provided by strapi
module.exports = ({ env }) => ({
upload: {
config: {
breakpoints: {
xlarge: 1920,
large: 1000,
medium: 750,
small: 500,
xsmall: 64,
},
},
},
});

It Looks like this is an issue in sharp , Strapi server stop when it encounter this issue and because of that it return network error 502 .
to solve it in my code i had to extend the plugin-upload code and to change this const in that plugin to stop causing server to fail , then image can uploaded successfully , maybe without proper optimization but without failing .
on node_module/#strapi/plugin-upload/server/services/image-manipulation.js change this const
const transformer = sharp();
to this
const transformer = sharp({ failOnError: false });
Steps to Apply it to Strapi as plugin extension :
1 - extend the plugin-upload plugin by creating ( upload ) folder within src/extensions folder ( create extensions folder if it does not exist )
2 - Create a file named ( strapi-server.js ) with this content to overwrite the image-manupilation service :
'use strict';
const imageManipulate = require('./server/services/image-manipulation')
module.exports = (plugin) => {
plugin.services['image-manipulation'] = imageManipulate;
return plugin;
};
3 - Copy ( utils folder + services/image-manipulation.js) from node_module/#strapi/plugin-upload/server to your extensions folder .
4 - Edit transformer const in image-manipulation.js as discussed before .
For more information about the sharp issue see here : https://github.com/lovell/sharp/issues/1859
For more information about Extending Strapi Plugin see here : https://docs.strapi.io/developer-docs/latest/development/plugins-extension.html

Related

threejs loading of gltf results to 404 (Not found) using nodejs express

I know this is common errors but i tried the answers in stackoverflow but it doesnt work.
i am loading a gltf file from this tutorial : https://threejsfundamentals.org/threejs/lessons/threejs-load-gltf.html
I am using nodejs express as my server and my directory structure is
where in public is set as the public folders like this
app.use(express.static('public'));
inside the public folder contains the necessary threejs library files and GLTF loader,
so since the public folder is already 'public' and exposed it also contains the assets or the gltf files
However, when loading the gltf file from this directory, it results to 404.
const loader = new GLTFLoader();
loader.load('assets/city/scene.gtlf',
(gltf) => {
const root = gltf.scene;
scene.add(root);
},
(xhr)=>{
},
(error)=>{
console.log(error);
});
What I am missing here?

AssertionError [ERR_ASSERTION]: Cannot wrap non-Error object

When i try to upload Image using strapi on cloudinary then it says internal server error on strapi backend and gives me this error AssertionError [ERR_ASSERTION]: Cannot wrap non-Error object in terminal. I don't know what is the problem, Help me to resolve this issue thanx
Step 1: Create a directory path './config/plugins.js' from the root of your Strapi application
Copy and paste the code below in your plugins.js file and change the details of the providerOptions object.
// ./config/plugins.js
if (process.env.NODE_ENV === "production") {
module.exports = ({ env }) => ({
// ...
upload: {
provider: "cloudinary",
providerOptions: {
cloud_name: env("process.env.CLOUDINARY_NAME"),
api_key: env("process.env.CLOUDINARY_KEY"),
api_secret: env("process.env.CLOUDINARY_SECRET"),
},
},
// ...
});
} else {
module.exports = {};
}
Step 2: Create a .env file at the root of your Strapi application. Copy your api secret, api key and api environment variable from your cloudinary dashboard and save in the .env file.
CLOUDINARY_URL=cloudinary://CLOUDINARY_API_KEY:CLOUDINARY_API_KEY#CLOUDINARY_NAME
CLOUDINARY_NAME=CLOUDINARY_NAME
CLOUDINARY_API_KEY=CLOUDINARY_API_KEY
CLOUDINARY_API_KEY=CLOUDINARY_API_KEY
This worked for me. I hope it should work for you too.

How to share a local photo using React Expo Sharing.shareAsync?

I'm trying to share a local file in React Expo using Sharing.shareAsync(). Retrieved photo info using MediaLibrary.getAssetInfoAsync() (on Android):
"filename": "IMG_20200414_190459.jpg",
"height": 2074,
"id": "896",
"localUri": "file:///storage/emulated/0/DCIM/Camera/IMG_20200414_190459.jpg",
"location": null,
"mediaType": "photo",
"modificationTime": 1586905500000,
"uri": "file:///storage/emulated/0/DCIM/Camera/IMG_20200414_190459.jpg",
"width": 4608,
Calling Sharing.shareAsync(photo.localUri, {mimeType: 'image/jpeg'} I get the error Failed to share the file: Failed to find configured root that contains /storage/emulated/0/DCIM/Camera/IMG_20200414_190459.jpg. So I tried removing one of the slashes after file: and get the error Not allowed to read file under given URL.
App has CAMERA_ROLL and CAMERA permissions and app.json includes:
"android": {
"permissions": [
"CAMERA",
"CAMERA_ROLL",
"READ_EXTERNAL_STORAGE",
"WRITE_EXTERNAL_STORAGE"
]
}
Expo docs say I should be able to share a local file. Not sure what I'm doing wrong or what to try next. TIA.
This is a problem with the share API. You can get over this using the expo-image-manipulation.
As an example:
import * as ImageManipulator from "expo-image-manipulator";
const openShareDialogAsync = async () => {
let imageProc = await ImageManipulator.manipulateAsync(yourImageUri);
// this returns an object including the uri
await Sharing.shareAsync(imageProc.uri);
}
It looks like this may be a bug in the Sharing API. You can work around it for now by copying the file to your document directory and then sharing from there. Here's an example: https://snack.expo.io/#notbrent/share-media-library-photo
Relevant code from that example below:
// Placeholder for getting asset from MediaLibrary
let results = await MediaLibrary.getAssetsAsync({ first: 1 });
let asset = results.assets[0];
// Use FileSystem to copy the image from its original location to the app document directory
let assetUriParts = asset.uri.split("/");
let assetName = assetUriParts[assetUriParts.length - 1];
let uri = `${FileSystem.documentDirectory}/${assetName}`;
await FileSystem.copyAsync({
from: asset.uri,
to: uri,
});
// Share the image from the uri that you copied it to
Sharing.shareAsync(uri);

form post with file attach throws network error / React Native + react native Image picker

I am using react-native-image-picker to fetch image details and try to upload in https backend server. the request is not successful and it throws network error. It did not esablish the connection with the backend server. The problem is with formdata that I am sending. Can you please suggest header and other information, if I missed out.
export const postImage = async state => {
let formData = new FormData();
formData.append('image', {
uri : state.photo.uri,
type: state.photo.type,
name : state.photo.fileName
});
const config = {
headers: {
'Content-Type': 'multipart/form-data',
Accept: "application/x-www-form-urlencoded",
'Accept': 'application/json'
},
};
try {
return $http.post('/image/save', formData, config)
.then(response => response)
.catch(error => error)
} catch(error) {
console.log(error)
}
}
Environment:
- Axios Version ^0.19.2
- Additional Library Versions [React 16.11.0, React Native 0.62.1]
There's an issue with flipper, upgrading it to 0.39.0 and above works
This issue is being tracked here: https://github.com/facebook/react-native/issues/28551
Fix: https://github.com/facebook/flipper/issues/993#issuecomment-619823916
This should be fixed in version 0.39.0. To upgrade, edit android > gradle.properties
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.39.0 // edit this manually
This issue took me more than 5 hours to resolve. I was about to give up when I was finally able to resolve the issue.
The issue that I was facing which is close to what you are mentioning is that I was getting NetworkError when using expo-image-picker and trying to upload the file using axios. It was working perfectly in iOS but not working in android.
This is how I solved the issue.
There are two independent issues at action here. Let's say we get imageUri from image-picker, then we would use these following lines of code to upload from the frontend.
const formData = new FormData();
formData.append('image', {
uri : imageUri,
type: "image",
name: imageUri.split("/").pop()
});
The first issue is with the imageUri itself. If let's say photo path is /user/.../path/to/file.jpg. Then file picker in android would give imageUri value as file:/user/.../path/to/file.jpg whereas file picker in iOS would give imageUri value as file:///user/.../path/to/file.jpg.
The solution for the first issue is to use file:// instead of file: in the formData in android.
The second issue is that we are not using proper mime-type. It is working fine on iOS but not on Android. What makes this worse is that the file-picker package gives the type of the file as "image" and it does not give proper mime-type.
The solution is to use proper mime-type in the formData in the field type. Ex: mime-type for .jpg file would be image/jpeg and for .png file would be image/png. We do not have to do this manually. Instead, you can use a very famous npm package called mime.
The final working solution is:
import mime from "mime";
const newImageUri = "file:///" + imageUri.split("file:/").join("");
const formData = new FormData();
formData.append('image', {
uri : newImageUri,
type: mime.getType(newImageUri),
name: newImageUri.split("/").pop()
});
This is an issue with flipper.Upgrade the flipper version in gradle.properties to 0.43.0+ and it will be fixed
Make sure the mime type matches the file you are uploading.
For me, it was the issue.
change this line: form_data.append('image', data);
To form_data.append('image', JSON.stringify(data));
where data is from the image picker.
from https://github.com/react-native-image-picker/react-native-image-picker/issues/798
You need to add this uesCleartextTraffic="true" to the AndroidManifest.xml file found inside the dir android/app/src/main/AndroidManifest.xml
<application ... android:usesCleartextTraffic="true"> Then, Because of issue with Flipper Network.
I commented initializeFlipper(this, getReactNativeHost().getReactInstanceManager())
in this file /android/app/src/main/java/com/{your_project}/MainApplication.java
Also, commenting out line number 43 in this file android/app/src/debug/java/com/**/ReactNativeFlipper.java
line43: builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
None of the issues in the other answers were causing my problem, but after digging more into Axios error response, I found out that Nginx was responding with error 413 Request Entity Too Large.
Adding client_max_body_size 50M to the http section of nginx.conf file solved the issue.

Jest snapshots for react native static images throwing warnings

I am trying to write snapshots tests to check if the correct image is being returned. When I just use zero transforms than the result is always '1' which isnt very helpful. I went onto the site and added this to my package.json
"transform": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/jest/fileTransformer.js"
}
and create a file called fileTransformer that looks like this
// fileTransformer.js
const path = require('path');
module.exports = {
process(src, filename, config, options) {
return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
},
};
Now the tests are resulting in useful snapshots which is great, however im not getting warnings in my console that look like this
console.error node_modules/prop-types/checkPropTypes.js:20
Warning: Failed prop type: Invalid prop `source` supplied to `Image`.
in Image
You can take a look at moduleNameMapper configuration
"^[./a-zA-Z0-9$_-]+\\.png$": "<rootDir>/RelativeImageStub.js",
and inside the file you can export a dummy image path
RelativeImageStub.js
export default '/dummy/path/to/dummyImage.png';
You should also be able to mock the result from importing the image:
Component.spec.js
import Component from './Component';
jest.mock('./path/to/the/image.png', () => "dummy/path/image.png");
Component.js
import image from './path/to/the/image.png';
export default function Component() {
return <Image source={image} />;
}
This way you'll also get an error if the specified path does not exists.