Tôi muốn thay đổi DPI bằng ImageMagick mà không thay đổi kích thước byte thực của dữ liệu hình ảnh


45

Trong GIMP có một cách rất đơn giản để làm những gì tôi muốn. Tôi chỉ cài đặt hộp thoại tiếng Đức nhưng tôi sẽ cố gắng dịch nó. Tôi đang nói về việc đi đến Picture -> PrintingSizevà sau đó điều chỉnh các Giá trị X-ResolutionY-Resolutionđược gọi là giá trị DPI. Bạn cũng có thể chọn định dạng theo mặc định Pixel/Inch. (Trong tiếng Đức, thoại là Bild -> Druckgrößevà có X-AuflösungY-Auflösung)

Ok, các giá trị thường có 72theo mặc định. Khi tôi thay đổi chúng thành ví dụ: 300điều này có tác dụng là hình ảnh vẫn giữ nguyên trên máy tính, nhưng nếu tôi in nó, nó sẽ nhỏ hơn nếu bạn nhìn vào nó, nhưng tất cả các chi tiết vẫn ở đó, chỉ nhỏ hơn -> nó có độ phân giải cao hơn trên giấy in (nhưng kích thước nhỏ hơn ... phù hợp với tôi).

Tôi thường làm điều đó khi tôi làm việc với LaTeX hoặc chính xác với lệnh pdflatextrên Ubuntu-Machine gần đây. Khi tôi thực hiện quy trình trên với GIMP bằng tay, mọi thứ đều hoạt động tốt. Các hình ảnh sẽ xuất hiện nhỏ hơn trong tệp PDF kết quả nhưng với chất lượng in cao.

Những gì tôi đang cố gắng làm là tự động hóa quá trình đi vào GIMP và điều chỉnh các giá trị DPI. Vì ImageMagick được biết đến là tuyệt vời và tôi đã sử dụng nó cho nhiều nhiệm vụ khác, tôi đã cố gắng đạt được mục tiêu của mình với công cụ này. Nhưng nó không làm những gì tôi muốn.

Sau khi thử rất nhiều thứ, tôi nghĩ đây thực sự là mệnh lệnh nên là bạn của tôi:

convert input.png -density 300 output.png

Điều này sẽ đặt DPI thành 300, vì tôi có thể đọc ở mọi nơi trên web. Nó dường như làm việc. Nhưng khi tôi kiểm tra tệp thì nó vẫn giữ nguyên (EDIT: đó là những gì tôi mong đợi, như đã giải thích ở trên).

file input.png output.png
     input.png: PNG image data, 611 x 453, 8-bit grayscale, non-interlaced
    output.png: PNG image data, 611 x 453, 8-bit grayscale, non-interlaced

Khi tôi sử dụng lệnh này, có vẻ như nó đã làm những gì tôi muốn:

identify -verbose output.png | grep 300
    Resolution: 300x300
    PNG:pHYs                 : x_res=300, y_res=300, units=0

Hài hước lắm, cùng một đầu ra input.pngkhiến tôi bối rối ... vậy đây có thể là thông số sai để xem không?

Nhưng khi tôi kết xuất TeX của mình với pdflatexhình ảnh vẫn còn lớn và mờ. Ngoài ra khi tôi mở lại hình ảnh bằng GIMP, các giá trị DPI được đặt thành 72thay vì 300. Vì vậy, thực sự không có hiệu lực nào cả.

Bây giờ vấn đề ở đây là gì. Tôi nhận được một cái gì đó hoàn toàn sai? Tôi không thể sai vì mọi thứ đều hoạt động tốt với GIMP.

Cảm ơn cho bất kỳ sự giúp đỡ trong việc này. Tôi cũng sẵn sàng cho các giải pháp tự động khác dễ dàng thực hiện trên hệ thống Linux.


user1694804: Bạn nên nhớ quay lại câu trả lời của Martin Wilson và 'upvote' nó (nhấp vào ^biểu tượng nhỏ bên trái câu trả lời của anh ấy), không chỉ 'chấp nhận' ngay khi bạn có đủ danh tiếng cá nhân (tôi nghĩ bạn cần +15) ...
Kurt Pfeifle

Câu trả lời:


76

Chỉ định các đơn vị - Tôi dường như nhớ có vấn đề khi tôi bỏ qua tùy chọn này (mặc dù DPI phải là mặc định), ví dụ:

convert -units PixelsPerInch input.png -density 300 output.png

Bạn có biết các trường dữ liệu nhúng mà GIMP sử dụng để đọc độ phân giải - nó có riêng để ghi đè lên các trường tiêu chuẩn được sử dụng bởi ImageMagick không? Ví dụ: Photoshop sử dụng Photoshop:XResolutionPhotoshop:YResolutiondo đó bạn phải đặt những thứ này cho Photoshop để nhận ra cài đặt mật độ (ImageMagick không thể làm điều này - chúng tôi sử dụng ExifTool).


2
Tôi cần phải đặt -density 300trước input.png. Tôi đã chuyển đổi các tệp PDF. Dù sao cũng cảm ơn bạn.
akostadinov

Để chuyển đổi PNG sang TIFF tôi cần sử dụng -set units PixelsPerInch -density 300, đơn giản -unitskhông hoạt động bất kể thứ tự của các tùy chọn.
Andrey

5

Lưu ý rằng bạn có thể sử dụng Exiftool để đọc độ phân giải. Ví dụ: Exiftool '-*resolution*' c.jpgcó thể hiển thị

Đơn vị phân giải: inch X Độ phân giải: 300 Y Độ phân giải: 300

Exiftool cũng có thể thiết lập các tham số, nhưng như đã lưu ý trong trang man Image::ExifTool::TagNames, Thẻ phụ XResolution và YResolution không thể ghi được bằng Exiftool.

Tôi không biết liệu ImageMagick có các tùy chọn thay đổi độ phân giải hay không, nhưng sẽ rất ngạc nhiên nếu nó không. Ngoài ra, thật đơn giản để viết các tập lệnh GIMP để tự động hóa các tác vụ như thế này và cũng có thể thay đổi độ phân giải bằng các chương trình nhỏ. Ví dụ, sau đây là một chương trình C (có thể biên dịch qua gcc setRes.c -O3 -Wall -o setRes) để đọc một vài byte đầu tiên của tệp jpeg, thay đổi độ phân giải thành 300 và viết lại chúng. Chương trình như được hiển thị sử dụng các hằng số cho các máy cuối nhỏ, như x86. Nếu chạy trên một máy lớn, nó sẽ chấm dứt với một thông báo như thế Error: xyz may be not a .jpg file, ngay cả khi xyz tệp jpeg. Lưu ý, tôi đã không kiểm tra các hình ảnh kết quả thông qua pdflatex; bạn có thể sẽ thấy đáng để gửi một câu hỏi trong tex SE .

/* jiw -- 24 Sep 2012 -- Re: set resolution in a jpg -- Offered without
warranty under GPL v3 terms as at http://www.gnu.org/licenses/gpl.html
*/
#include <stdlib.h>
#include <stdio.h>
void errorExit(char *msg, char *par, int fe) {
  fprintf (stderr, "\n%3d Error: %s %s\n", fe, msg, par);
  exit (1);
}
// Note, hex constants are byte-reversed on little vs big endian machines
enum { JF=0x464a, IF=0x4649, L300=0x2c01, B300=0x012c, NEWRES=L300};
int main(int argc, char *argv[]) {
  FILE *fi;
  short int buf[9];
  int r, L=sizeof buf;
  if (argc<2) errorExit(argv[0], "requires a .jpg file name", 0);
  fi = fopen(argv[1], "r+b");
  if(!fi) errorExit("open failed for", argv[1], ferror(fi));
  r = fread(buf, 1, L, fi);
  if (r != L) errorExit("read failed for", argv[1], ferror(fi));
  if (buf[3] != JF || buf[4] != IF) // Check JFIF signature
    errorExit(argv[1], "may be not a .jpg file", 0);
  buf[7] = buf[8] = NEWRES;
  fseek(fi, 0, SEEK_SET);
  r = fwrite(buf, 1, L, fi);
  if (r != L) errorExit("write failed for", argv[1], ferror(fi));
  return 0;
}

1
Điều này không giúp tôi nhiều, vì tôi đang xử lý PNG và không có nhiều manh mối về JPG hay thậm chí C. Đó là kiến ​​thức "sâu sắc" đối với tôi có ích. Có lẽ người khác có thể sử dụng nó.
Boris Däppen

Vâng, tôi nên đã chú ý hơn đến câu hỏi! Đọc lại nó, JPG không được đề cập, PNG rõ ràng là.
James Waldby - jwpat7

Có, tôi là người khác và tôi có thể sử dụng nó: Tôi đã mở tệp .jpg của mình trong trình chỉnh sửa hex và chỉnh sửa byte thứ chín và thứ mười một cho mật độ dọc và ngang. Có thể nói tôi "thực thi" mã của bạn bằng tay.
u_Ltd.

2

Tôi không thể tìm ra cách thuyết phục chuyển đổi để chỉ thêm siêu dữ liệu và không mã hóa lại bitmap [đơn sắc] của mình; nó đã mở rộng tập tin> 50%.

Tôi phát hiện ra rằng pngcrush (không phải là công cụ ImageMagick) cũng có thể thêm siêu dữ liệu mật độ. Dòng lệnh này đánh dấu 600dpi và cho phép các tối ưu hóa khác, giúp giảm kích thước tệp xuống 10%:

pngcrush -res 600 in.png out.png

-1

"Tôi muốn thay đổi DPI bằng Imagemagick mà không thay đổi kích thước byte thực tế của dữ liệu hình ảnh."

Điều này là hoàn toàn không thể!

Bởi vì:

     more "Dots per Inch" 
<==> more pixels per area 
<==> more total pixels per image 
<==> more total bytes per image

Ngoài ra, bạn dường như không hiểu DPI trong thực tế là gì:

  1. Đó là một giá trị hoàn toàn trừu tượng chỉ nhận được giá trị thực tế trong bối cảnh biết cả kích thước tuyệt đối của bản in hoặc kết xuất trên màn hình hoặc màn hình:
    • Bạn có thể 'in' hình ảnh 72x72 pixel rất giống nhau trên một hình vuông rộng 1 inch: bản in sẽ có độ phân giải 72dpi.
    • Bạn cũng có thể 'in' nó trên một hình vuông rộng 1/4 inch: sau đó bản in sẽ có độ phân giải 288dpi.
    • ( Lưu ý: Nếu bạn 'in' nó 288dpitrên hình vuông 1 inch, nó không còn là hình ảnh giống nhau: nó sẽ trải qua một số phép ngoại suy thông qua trình điều khiển máy in hoặc một số cơ chế lọc khác và nó sẽ trở thành hình ảnh 288x288 pixel thay vì hình ảnh 72x72 pixel ... )
  2. Cả hai bản in sẽ có thông tin hình ảnh rất giống nhau - hình ảnh 288dpi sẽ không đột nhiên có nhiều hơn.

Nếu bạn muốn in 72x72 pixel gốc hình ảnh như 1 inch rộng vuông, nhưng ít 288dpi, sau đó bạn sẽ phải rescale hình ảnh (trong trường hợp này nhân rộng nó lên). Đối với mỗi 1 pixel trong bản gốc, bạn sẽ cần 4 pixel của hình ảnh mới, được nâng cấp. Bây giờ có các thuật toán khác nhau có thể được sử dụng để tính toán giá trị màu nào cho 4 pixel này (3 trong số chúng là pixel mới) nên có:

  • bạn có thể cung cấp cho chúng giống như pixel gốc (là thuật toán rất "thô",
  • hoặc bạn có thể thực hiện một số giá trị trung bình của giá trị màu của pixel gốc với các giá trị màu của các pixel lân cận.

Trong mọi trường hợp, bạn đang tạo một hình ảnh lớn hơn bao gồm 288 hàng pixel, mỗi pixel cao 288 pixel (288x288 pixel).

Những gì Gimp làm cho bạn khi bạn trải qua "Hình ảnh -> Kích thước in": nó đơn giản hóa quá trình tính toán lại các thay đổi cần thiết trong kích thước pixel tuyệt đối, làm cho nó thân thiện hơn với người dùng. Vì mục đích này...

  • ... trước tiên, bạn hỏi bạn về DPI vì một máy in nhất định không thể thay đổi độ phân giải in tùy ý (một số có thể cung cấp không chỉ một, mà thậm chí có thể 2 hoặc 3 độ phân giải khác nhau). Vì vậy, nó hỏi bạn ở độ phân giải bạn muốn in. Đó là thông tin đầu tiên.
  • ... sau đó nó cũng yêu cầu các mảnh thứ hai của thông tin: tại mà kích thước (trong cm, mmhoặc inch) các bản in sẽ xuất hiện trên giấy.

Theo hai mẩu thông tin này, Gimp sau đó tính toán tổng số pixel mà nó phải sử dụng (ngoại suy từ số pixel ban đầu) để lấp đầy không gian được yêu cầu ở độ phân giải được yêu cầu.

Tuy nhiên, việc nhân rộng một hình ảnh raster bằng cách làm cho nó chứa nhiều pixel hơn sẽ không thêm thông tin thực vào nó và nó chỉ thêm "chất lượng" cho nó là hư cấu. Nó có thể trông đẹp hơn mắt người nếu thuật toán mở rộng của bạn là một 'tốt'. Và nó sẽ trông xấu, nếu bạn chỉ tăng gấp đôi, gấp ba hoặc gấp bốn pixel hiện có, giống như một số thuật toán đơn giản làm.

Đối với hình ảnh raster,
cài đặt DPI chỉ có liên quan trong bối cảnh in hoặc hiển thị nó. Bởi vì máy in hoặc màn hình đã cho, độ phân giải cố định. Do đó, thông tin chỉ ...

  • ... trình điều khiển máy in hoặc
  • ... một ứng dụng xử lý ảnh hỗ trợ in

cần phải biết.

tài liệu của ImageMagick hoàn toàn đồng ý với tôi:

-density width
-density widthxheight
Đặt độ phân giải ngang và dọc của hình ảnh để hiển thị cho các thiết bị.

Đối với hình ảnh vector hoặc định dạng tệp
(như PDF hoặc PostScript), tuy nhiên, cài đặt DPI cực kỳ quan trọng trong bối cảnh raster hóa chúng. DPI cao hơn sẽ chuyển nhiều thông tin hình ảnh hơn sang định dạng raster và do đó bảo tồn nhiều chi tiết hơn từ chất lượng ban đầu thực sự. Khi chuyển đổi một hình ảnh vector của một kích thước nhất định trongmm,cmhoặcinchvào raster với DPI cao hơn sẽ trực tiếp chuyển thành một số cao hơn tổng số điểm ảnh trong hình ảnh.

Ngoài ra, ImageMagick không hỗ trợ 'in' như vậy. Thay vào đó, ImageMagick chỉ ...

  • ... chuyển đổi các tập tin từ một định dạng raster nhất định sang các định dạng raster khác;
  • ... hoặc nó thu nhỏ hoặc thu nhỏ hình ảnh raster;
  • ... Hoặc nó thay đổi giá trị màu theo một thuật toán cụ thể;
  • ... Hoặc nó cắt hình ảnh, phủ chúng, đảo ngược chúng, phản chiếu chúng;
  • ... và những gì không ....

... Nhưng để in các hình ảnh bị thao túng, bạn cần sử dụng một chương trình khác.

Một số định dạng hình ảnh (TIFF, PNG, ...) không hỗ trợ lưu trữ cài đặt DPI bên trong dữ liệu meta của chúng.

Nhưng đây không phải là một thuộc tính 'gợi ý' không làm thay đổi hình ảnh raster bên dưới. Đó là lý do tại sao bạn thực hiện khám phá này:

"Khi tôi kiểm tra tập tin, nó vẫn giữ nguyên."

'Gợi ý' này có thể có thể được đánh giá tự động bởi trình điều khiển máy in hoặc bằng các chương trình tạo trang như LaTeX. Trong trường hợp không có 'gợi ý' của DPI như vậy (hoặc nếu bằng cách nào đó họ không thể hiện bản thân theo cách LaTeX mong đợi họ làm), LaTeX vẫn có thể được lệnh hiển thị bất kỳ hình ảnh cụ thể nào trên trang theo cách mà người ta mong đợi để - nó chỉ cần một số mã LaTeX rõ ràng hơn xung quanh hình ảnh!

Một số định dạng hình ảnh khác (JPEG (?), BMP, ...) thậm chí không hỗ trợ lưu trữ gợi ý DPI tại dữ liệu meta bên trong của chúng.

Vì vậy, Gimp chỉ hỗ trợ những gì bạn thấy với "Hình ảnh -> Kích thước in" vì nó muốn in một hình ảnh. Với ImageMagick bạn không thể in.

Tiếp tục làm những gì bạn muốn làm với Gimp khi bạn in. Nó không có ý nghĩa với ImageMagick.

Xem thêm đoạn tài liệu IM bổ sung này , giải thích cùng một chủ đề bằng các từ khác nhau.


Vì vậy, những gì còn lại là đây:

  • Nếu bạn 'thao tác' hình ảnh của mình bằng Gimp, rồi nhúng kết quả vào LaTeX, trang sẽ trông giống như bạn mong đợi.
  • Nếu bạn 'thao tác' hình ảnh của mình bằng ImageMagick, sau đó nhúng kết quả vào LaTeX, trang sẽ trông không như bạn mong đợi.

Vui lòng cung cấp các thông tin sau để giải quyết vấn đề trên:

  • phiên bản chính xác của cài đặt ImageMagick của bạn (đầu ra hoàn chỉnh convert -versionconvert -list configure);
  • (một liên kết đến một) hình ảnh mẫu ban đầu;
  • (một liên kết đến) cùng một hình ảnh được thao tác bởi Gimp;
  • (một liên kết đến) cùng một hình ảnh được thao tác bởi ImageMagick.

Bằng cách này chúng ta có thể giúp giải quyết vấn đề.

Nhưng lưu ý: đây là một vấn đề khác với những gì chủ đề / tiêu đề hiện tại của bạn yêu cầu: "Tôi muốn thay đổi DPI bằng Imagemagick mà không thay đổi kích thước byte thực của dữ liệu hình ảnh"


Cập nhật

vẫn chưa rõ ràng với một số độc giả những gì tôi đã lưu ý ở trên, đây là một nỗ lực nữa ...

Bất cứ điều gì được ghi chú là 'Độ phân giải' hoặc 'Mật độ' trong tệp hình ảnh, đều là thuộc tính siêu dữ liệu . Nó không ảnh hưởng đến số lượng pixel thực tế được mô tả bởi tệp và hoàn toàn không liên quan về mặt này. Nó chỉ là một gợi ý mà một thiết bị in hoặc kết xuất hoặc ứng dụng có thể hoặc không thể làm theo khi in, kết xuất hoặc hiển thị hình ảnh.

Đối với mục đích này, nó chỉ là một vài số được lưu trữ trong tệp hình ảnh. Những con số này cho biết các thiết bị đầu ra như máy in và hiển thị bao nhiêu chấm (hoặc pixel) trên mỗi inch hình ảnh sẽ được hiển thị tại. Đối với các định dạng vectơ như PostScript, PDF, MWF và SVG, nó cho biết tỷ lệ pixel để vẽ bất kỳ tọa độ thế giới thực nào được sử dụng bởi hình ảnh.

Một ví dụ, trong đó giá trị độ phân giải được ImageMagick lưu ý bên trong siêu dữ liệu hình ảnh KHÔNG được vinh danh bởi một ứng dụng là Adobe Photoshop. Photoshop lưu trữ các gợi ý về độ phân giải in hoặc hiển thị mong muốn trong một cấu hình độc quyền có tên 8bim . ImageMagick không chạm vào hồ sơ này, ngay cả khi được yêu cầu viết thay đổi độ phân giải thành siêu dữ liệu của tệp hình ảnh. Mặt khác, Photoshop sẽ bỏ qua tất cả các gợi ý về độ phân giải được ImageMagick lưu trữ trong trường siêu dữ liệu tiêu chuẩn khác được xác định cho mục đích này ngay khi nhìn thấy hồ sơ 8bim của chính nó .

OP nên chọn tiêu đề:

  • 'Tôi muốn thay đổi DPI (gợi ý độ phân giải siêu dữ liệu) bằng ImageMagick mà không thay đổi số pixel thực tế trong ảnh'

để tránh mọi hiểu lầm ...


1
"Khi tôi kiểm tra tập tin, nó vẫn giữ nguyên." ĐÂY LÀ CÁI TÔI MUỐN. TÔI KHÔNG NÓI TRONG VĂN BẢN NÀY MẮT TÔI. XIN VUI LÒNG ĐỌC CÂU HỎI CỦA TÔI MỘT LẦN NỮA ... SLOWLY ... ARGL
Boris Däppen

6
"Điều này là hoàn toàn không thể!" Không, điều đó là có thể ... chỉ là hình ảnh bị co lại khi được in. Điều mà tôi đã giải thích rất chi tiết trong câu hỏi của mình
Boris Däppen

5
Thế nào là bạn thậm chí nói về. Tôi đã giải thích chi tiết trường hợp sử dụng của mình trong câu hỏi. Nếu bạn trả lời các câu hỏi chỉ bằng tiêu đề, bạn không phải là người giúp đỡ ở đây.
Boris Däppen

4
Lỗ hổng nghiêm trọng của bạn là giả định ban đầu: "nhiều pixel trên mỗi khu vực <==> tổng số pixel trên mỗi hình ảnh" Điều đó chỉ đúng nếu diện tích không đổi. Đây không phải là trường hợp.
Leo Izen

1
Đúng. DPI chỉ có ý nghĩa nếu được hiển thị cho thiết bị. Nó cũng là một trường có thể được lưu trữ trong một tệp hình ảnh khi độ phân giải này có liên quan. Câu hỏi rõ ràng hỏi làm thế nào để thay đổi trường này mà không thay đổi dữ liệu pixel.
Leo Izen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.