2012-01-19 50 views
-2

我已經在世界各地兩次半試圖解決一個有大量圖像的奇怪問題。修改JPEG文件的標題以正確匹配格式

我需要的是知道如何讀取和寫入JPEG文件頭中的第4和第18個字節。如果它們匹配某些屬性,我需要做一些特定的工作並調整這些字節以反映其他內容。我基本上將這些圖片的格式修改爲更加標準的格式,因爲德爾福不能識別它們的格式。

那麼如何讀取/寫入這些字節呢?我使用什麼?我對讀取圖像文件的原始數據一無所知,更不用說調整它了。


注意

刪除大部分的問題,因爲我從一開始就投入了太多的信息。

+2

這是不是一個真正的問題,是嗎?你要求有人爲你寫代碼。免費。 – cha0site

+0

我在問如何讀取/寫入JPEG文件的標題中的某些字節。而已。不應該那麼辛苦。 –

+0

你會更好地獲得處理圖像的解碼器。修改文件看起來很糟糕。 –

回答

3

的實際改變JPG頭的機制是很容易的。這並不意味着修復JPG很容易,只是如果您知道要更改什麼,您可以輕鬆完成。因爲這就是你要求的,所以下面是如何更改內存中的JPG標頭,將修改的JPG加載到TJpgImage中並將其轉換爲TBitmap。

請注意,我不認爲這是一個不錯的辦法。修復生成的位圖非常容易!請參閱我的新問題以解決如何修復位圖here的其他問題。

這裏就是你請求的代碼(如何改變JPG頭):

function LoadJpegIntoBitmap_HeaderFix(const FileName:string): TBitmap; 
var M: TMemoryStream; 
    P: PByteArray; 
    Jpg: TJPEGImage; 
begin 
    M := TMemoryStream.Create; 
    try 
    M.LoadFromFile(FileName); 
    if M.Size < 18 then raise Exception.Create('File too short.'); 
    P := M.Memory; 

    // Here you can manipulate the header of the JPG file any way you want. 
    if P[0] = $07 then P[3] := P[17] - P[0]*3; 

    // Now load the modified JPG into a TJpgImage 
    Jpg := TJPEGImage.Create; 
    try 
     Jpg.LoadFromStream(M); 

     // Convert to bitmap 
     Result := TBitmap.Create; 
     Result.Assign(Jpg); 

    finally Jpg.Free; 
    end; 

    finally M.Free; 
    end; 
end; 
+0

謝謝你,這裏唯一與我的問題有關的答案。這裏的人們不應該擔心*爲什麼*我正在做我正在做的事情,我的問題明確指出了一個簡單的任務。我試圖刪除我的問題,但不能因爲一個非常諷刺的答案。事實上,人們把我的問題放在離主題100萬英里的地方,讓我感到激動。 –

2

下面是一些非常快速的僞代碼。稍後我會改進它。我必須跑步。

Assign the Adobe JPEG image file to a TFileStream 
Read first 18 bytes and use CompareMem to see if signature matches Adobe RGB JPEG 
If RGB JPEG then 
    We'll either: 
    Load from stream and tweak the header as we load 
    OR 
    Load from stream, copy to TBitmap, and use ScanLine to fix RGB 
Else 
    Load from stream, normally 

提示,請參閱LoadFromStream()而不是LoadFromFile()

我不知道你對圖像做了什麼後,所以可能還有一些工作要做。

+0

這是很好的pseduo代碼,但惡魔是在細節。我不知道'TBitmap'是什麼,但是如果它需要解碼JPEG,那麼這可能就是要走的路 - 以位圖形式處理數據比調整JFIF「標題」容易得多。 – cha0site

+0

這是最標準的(在delphi中)圖形對象。一切工作與'TBitmap'。 –

+0

@jerry cha0site有每個業務評論。您的評論非常不合適。 –

2

對,所以你的選擇是在這裏(因爲我們已經完全排除了任何任何第三方代碼):

  1. 一些德爾福大師(這我當然不是)出來的木製品和照亮着我們存在標準的Delphi庫代碼來處理這個問題,或者,您可以編寫自己的JPEG元數據解碼庫。

由於我不能幫你的第一個選項,這裏有一些參考,同時追求第二,你需要:

  • Wikipedia's JPEG article - wiki上更好的書面文章之一。這個毛茸茸的主題很棒的介紹材料。
  • ITU T.81 - 原始的JPEG規範。最重要的位在附件B中,但是這實際上描述了一種稱爲JIF的格式,它實際上並未被使用。但是,JFIF和EXIF都是基於它。
  • ICC - 這指定ICC(國際色彩聯盟)配置文件,這是您的標題似乎有點錯誤。
  • ICC 2010 - 以上規格的新版本,其中Errata
  • JFIF - 大多數JPEG文件實際使用的格式。
  • EXIF - JPEG文件使用的另一種格式,尤其是那些源自數碼相機的格式。
  • ITU T.84 - 不太有用,它描述了JPEG擴展。爲了完整性,我在這裏包括它。

可悲的是,沒有一個公共領域JPEG實現,我所知道的(任何語言)的實際處理的標準,即EXIF和ICC配置文件中的相關位,所以我不能給你任何代碼你可以從中吸取靈感。最好看的地方可能是libexif,但這是GPL。

你要做的是將JPEG文件作爲常規文件讀取,根據從上述文檔中收集的信息解析輸入,進行必要的更改並將其寫回。我不認爲這會很容易,但顯然這是你會接受的唯一解決方案。

祝你好運!

3

甚至不認爲你可以手動調整您的JPEG文件的第一個x字節。

因爲它已經被解釋的那樣,JPEG格式多種形式和非常複雜的。如此多的一些常用庫不能處理所有可接受的格式。打開一個libjpeg.h並查看可以在jpeg文件中找到的一堆頭結構。

如果你想在不改變數據的情況下修改你的頭文件,你仍然需要用一個庫來打開JPEG文件,這個庫會移交適當的結構,以修改相關的標誌並將其保存爲想要的格式。

要麼找到在Delphi編寫或與德爾福接口庫,並用它來建立你的批量轉換,或者在你的應用程序中打開一個JPEG時,在飛行轉換格式。

如果您知道定義問題文件的屬性/標誌的確切組合,您可以調整jpeg.pas單位以適應您的需要,如我在previous answer中所示。